bitkeeper revision 1.772 (404f1bca1AESVwPe-EoPH5HymQhTXQ)
authorkaf24@scramble.cl.cam.ac.uk[kaf24] <kaf24@scramble.cl.cam.ac.uk[kaf24]>
Wed, 10 Mar 2004 13:44:42 +0000 (13:44 +0000)
committerkaf24@scramble.cl.cam.ac.uk[kaf24] <kaf24@scramble.cl.cam.ac.uk[kaf24]>
Wed, 10 Mar 2004 13:44:42 +0000 (13:44 +0000)
xen.patchE

60 files changed:
.rootkeys
Makefile
xen/Makefile
xen/Rules.mk
xen/arch/x86_64/Rules.mk [new file with mode: 0644]
xen/include/asm-i386/config.h [new file with mode: 0644]
xen/include/asm-i386/ldt.h [new file with mode: 0644]
xen/include/asm-x86_64/apic.h [new file with mode: 0644]
xen/include/asm-x86_64/apicdef.h [new file with mode: 0644]
xen/include/asm-x86_64/atomic.h [new file with mode: 0644]
xen/include/asm-x86_64/bitops.h [new file with mode: 0644]
xen/include/asm-x86_64/byteorder.h [new file with mode: 0644]
xen/include/asm-x86_64/cache.h [new file with mode: 0644]
xen/include/asm-x86_64/config.h [new file with mode: 0644]
xen/include/asm-x86_64/cpufeature.h [new file with mode: 0644]
xen/include/asm-x86_64/current.h [new file with mode: 0644]
xen/include/asm-x86_64/debugreg.h [new file with mode: 0644]
xen/include/asm-x86_64/delay.h [new file with mode: 0644]
xen/include/asm-x86_64/desc.h [new file with mode: 0644]
xen/include/asm-x86_64/dma.h [new file with mode: 0644]
xen/include/asm-x86_64/domain_page.h [new file with mode: 0644]
xen/include/asm-x86_64/elf.h [new file with mode: 0644]
xen/include/asm-x86_64/fixmap.h [new file with mode: 0644]
xen/include/asm-x86_64/flushtlb.h [new file with mode: 0644]
xen/include/asm-x86_64/hardirq.h [new file with mode: 0644]
xen/include/asm-x86_64/hdreg.h [new file with mode: 0644]
xen/include/asm-x86_64/i387.h [new file with mode: 0644]
xen/include/asm-x86_64/ide.h [new file with mode: 0644]
xen/include/asm-x86_64/io.h [new file with mode: 0644]
xen/include/asm-x86_64/io_apic.h [new file with mode: 0644]
xen/include/asm-x86_64/ioctl.h [new file with mode: 0644]
xen/include/asm-x86_64/irq.h [new file with mode: 0644]
xen/include/asm-x86_64/ldt.h [new file with mode: 0644]
xen/include/asm-x86_64/mc146818rtc.h [new file with mode: 0644]
xen/include/asm-x86_64/mpspec.h [new file with mode: 0644]
xen/include/asm-x86_64/msr.h [new file with mode: 0644]
xen/include/asm-x86_64/page.h [new file with mode: 0644]
xen/include/asm-x86_64/param.h [new file with mode: 0644]
xen/include/asm-x86_64/pci.h [new file with mode: 0644]
xen/include/asm-x86_64/pda.h [new file with mode: 0644]
xen/include/asm-x86_64/pdb.h [new file with mode: 0644]
xen/include/asm-x86_64/pgalloc.h [new file with mode: 0644]
xen/include/asm-x86_64/processor.h [new file with mode: 0644]
xen/include/asm-x86_64/ptrace.h [new file with mode: 0644]
xen/include/asm-x86_64/rwlock.h [new file with mode: 0644]
xen/include/asm-x86_64/scatterlist.h [new file with mode: 0644]
xen/include/asm-x86_64/smp.h [new file with mode: 0644]
xen/include/asm-x86_64/smpboot.h [new file with mode: 0644]
xen/include/asm-x86_64/softirq.h [new file with mode: 0644]
xen/include/asm-x86_64/spinlock.h [new file with mode: 0644]
xen/include/asm-x86_64/string.h [new file with mode: 0644]
xen/include/asm-x86_64/system.h [new file with mode: 0644]
xen/include/asm-x86_64/time.h [new file with mode: 0644]
xen/include/asm-x86_64/timex.h [new file with mode: 0644]
xen/include/asm-x86_64/types.h [new file with mode: 0644]
xen/include/asm-x86_64/uaccess.h [new file with mode: 0644]
xen/include/asm-x86_64/unaligned.h [new file with mode: 0644]
xen/include/hypervisor-ifs/if-i386/hypervisor-if-arch.h [new file with mode: 0644]
xen/include/hypervisor-ifs/if-x86_64/hypervisor-if-arch.h [new file with mode: 0644]
xen/include/xeno/config.h

index 71702d606de23e3ab2df205b05c6548eb98e69f2..05d05306f7d5b4017a1b5aca673bf8a99cda9914 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 3ddb79bcOftONV9h4QCxXOfiT0h91w xen/arch/i386/traps.c
 3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/i386/usercopy.c
 3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/i386/xeno.lds
+404f1b91uzXgPOtIhs8UZPGbZvlHfg xen/arch/x86_64/Rules.mk
 3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
 3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c
 3ddb79bdrqnW93GR9gZk1OJe1qK-iQ xen/common/brlock.c
 3ddb79c3rM-Ote0Xn6Ytg8Y6YqAG-A xen/include/asm-i386/bitops.h
 3ddb79c3pXaTAGGWSIZF9EnRV5PlRw xen/include/asm-i386/byteorder.h
 3ddb79c3KhTI0F_Iw_hRL9QEyOVK-g xen/include/asm-i386/cache.h
+404f1b920OQVnrbnXnySS-WxrH9Wzw xen/include/asm-i386/config.h
 3ddb79c2LLt11EQHjrd6sB7FUqvFfA xen/include/asm-i386/cpufeature.h
 3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/include/asm-i386/current.h
 3ddb79c2jFkPAZTDmU35L6IUssYMgQ xen/include/asm-i386/debugreg.h
 3ddb79c2TKeScYHQZreTdHqYNLbehQ xen/include/asm-i386/io_apic.h
 3ddb79c3S9Tga4XZRPrD4-aN3XIV6w xen/include/asm-i386/ioctl.h
 3ddb79c2L7rTlFzazOLW1XuSZefpFw xen/include/asm-i386/irq.h
+404f1b93OjLO4bFfBXYNaJdIqlNz-Q xen/include/asm-i386/ldt.h
 3ddb79c3I98vWcQR8xEo34JMJ4Ahyw xen/include/asm-i386/mc146818rtc.h
 3ddb79c3n_UbPuxlkNxvvLycClIkxA xen/include/asm-i386/mpspec.h
 3ddb79c2wa0dA_LGigxOelSGbJ284Q xen/include/asm-i386/msr.h
 3ddb79c4HugMq7IYGxcQKFBpKwKhzA xen/include/asm-i386/types.h
 3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-i386/uaccess.h
 3ddb79c3uPGcP_l_2xyGgBSWd5aC-Q xen/include/asm-i386/unaligned.h
+404f1b95z0B0jb2IfvZJ7uvmYqsqpg xen/include/asm-x86_64/apic.h
+404f1b95_OZH-rw_durHSa_Kgdo95A xen/include/asm-x86_64/apicdef.h
+404f1b967UWSPkB0cwT9v-rilNzkHw xen/include/asm-x86_64/atomic.h
+404f1b97UDomt73PizniyrCaxVRkXQ xen/include/asm-x86_64/bitops.h
+404f1b98bhUJO45dacAaIRV7OE7P3A xen/include/asm-x86_64/byteorder.h
+404f1b99W-dMUlFpsvt--tVpQvNgEQ xen/include/asm-x86_64/cache.h
+404f1b9b_phpQlRnyiWqP6RodfZDpg xen/include/asm-x86_64/config.h
+404f1b9cz7UV611DK6CTY1ZAiwGtTw xen/include/asm-x86_64/cpufeature.h
+404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86_64/current.h
+404f1b9d854xae6HKv-9W8lLSgROdQ xen/include/asm-x86_64/debugreg.h
+404f1b9eRm9rtcM29P5O2nrPFOGSow xen/include/asm-x86_64/delay.h
+404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86_64/desc.h
+404f1ba05mjpUREtosjzz3PPL5cTJA xen/include/asm-x86_64/dma.h
+404f1ba13mnjeZT2ytPm0DB63703nA xen/include/asm-x86_64/domain_page.h
+404f1ba2IXQ7E0x9NlqpR5hgYtC9RQ xen/include/asm-x86_64/elf.h
+404f1ba31i0gS-cdqvd0RZX1HVnxsA xen/include/asm-x86_64/fixmap.h
+404f1ba4KXQ_V7HOkenF04KRU7Tl7w xen/include/asm-x86_64/flushtlb.h
+404f1ba5Sqzc22eXORShvCF9-rpMbA xen/include/asm-x86_64/hardirq.h
+404f1ba6_nDjomU9HJVvUugj63LvEg xen/include/asm-x86_64/hdreg.h
+404f1ba7Q-lF892SDZLWjJ62wmauSA xen/include/asm-x86_64/i387.h
+404f1ba8yxfnHH0NWC1B-wmd6bK2wg xen/include/asm-x86_64/ide.h
+404f1ba9_7NIylhSRmokesN8TNIiNg xen/include/asm-x86_64/io.h
+404f1baaiXXy7vChbzKmluSyJ5LWIw xen/include/asm-x86_64/io_apic.h
+404f1bab38sz6Fd2LyLPDD4mMYgd7w xen/include/asm-x86_64/ioctl.h
+404f1baceMqjaYFs7oZoNsPkaZJ0WQ xen/include/asm-x86_64/irq.h
+404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86_64/ldt.h
+404f1bae_yI5vMg-_k4EySMERbbz2Q xen/include/asm-x86_64/mc146818rtc.h
+404f1bafYfNwntXQGIggyj7D6YruJQ xen/include/asm-x86_64/mpspec.h
+404f1bb0asrts1dyLQhyARCgzhL0NA xen/include/asm-x86_64/msr.h
+404f1bb1LSCqrMDSfRAti5NdMQPJBQ xen/include/asm-x86_64/page.h
+404f1bb2IUaGWD82SrQFaacyBixVFw xen/include/asm-x86_64/param.h
+404f1bb3zSQfhMuQ24xNtq9Ed09jGw xen/include/asm-x86_64/pci.h
+404f1bb41Yl-5ZjIWnG66HDCj6OIWA xen/include/asm-x86_64/pda.h
+404f1bb5toGAnZVAlJ2fWWMv28DFJQ xen/include/asm-x86_64/pdb.h
+404f1bb6pz982jtehZacFKhFUac0ug xen/include/asm-x86_64/pgalloc.h
+404f1bb756fZfxk5HDx7J7BW3R-1jQ xen/include/asm-x86_64/processor.h
+404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86_64/ptrace.h
+404f1bb9K0pcyDrV4Ctva1HUczoueQ xen/include/asm-x86_64/rwlock.h
+404f1bbaIdS7vc3sE032fQG6EnY8AQ xen/include/asm-x86_64/scatterlist.h
+404f1bbbR5n83SiPof3joEPv9xWPPA xen/include/asm-x86_64/smp.h
+404f1bbc67CEECfR8ATd7dPD1ajLng xen/include/asm-x86_64/smpboot.h
+404f1bbdXaaPrIp5AUIjC8Hsp2H0Aw xen/include/asm-x86_64/softirq.h
+404f1bbeomkO5YarnkIRWxVhlB5EJA xen/include/asm-x86_64/spinlock.h
+404f1bbf82VK-kyDVBmR7CTvtTBKaw xen/include/asm-x86_64/string.h
+404f1bc0laOnGpDxFpgdiuZpEyOOKw xen/include/asm-x86_64/system.h
+404f1bc1FnfxOhmgWYHP97TPqA40Pw xen/include/asm-x86_64/time.h
+404f1bc2mx9ZbazcdFh-AN70ZvNMJQ xen/include/asm-x86_64/timex.h
+404f1bc3R2o0PIpQme8bDWeHcqHNGw xen/include/asm-x86_64/types.h
+404f1bc4tWkB9Qr8RkKtZGW5eMQzhw xen/include/asm-x86_64/uaccess.h
+404f1bc5idyWKKROGo_hvHVx58Gmkw xen/include/asm-x86_64/unaligned.h
 400304fcmRQmDdFYEzDh0wcBba9alg xen/include/hypervisor-ifs/COPYING
 3ddb79c2YTaZwOqWin9-QNgHge5RVw xen/include/hypervisor-ifs/block.h
 3ddb79c2PMeWTK86y4C3F4MzHw4A1g xen/include/hypervisor-ifs/dom0_ops.h
 3e6377eaioRoNm0m_HSDEAd4Vqrq_w xen/include/hypervisor-ifs/dom_mem_ops.h
 403cd194j2pyLqXD8FJ-ukvZzkPenw xen/include/hypervisor-ifs/event_channel.h
 3ddb79c25UE59iu4JJcbRalx95mvcg xen/include/hypervisor-ifs/hypervisor-if.h
+404f1bc68SXxmv0zQpXBWGrCzSyp8w xen/include/hypervisor-ifs/if-i386/hypervisor-if-arch.h
+404f1bc7IwU-qnH8mJeVu0YsNGMrcw xen/include/hypervisor-ifs/if-x86_64/hypervisor-if-arch.h
 3ead095dE_VF-QA88rl_5cWYRWtRVQ xen/include/hypervisor-ifs/kbd.h
 3ddb79c2oRPrzClk3zbTkRHlpumzKA xen/include/hypervisor-ifs/network.h
 3f0d22cbroqp_BkoDPwkfRJhaw1LiQ xen/include/hypervisor-ifs/vbd.h
index 2c9031ef0fe7e00588c0f9c1e9419410ce2d3161..f132263100c36a47d250dd06023b34d233b5d67f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -26,3 +26,4 @@ clean:
        $(MAKE) -C xen clean
        $(MAKE) -C tools clean
 
+       ln -sf if-$(ARCH) include/hypervisor-ifs/if-arch
index 4d2238af6be5897ee87b51cf9ee5e1db77357108..fc4bc7f96194da9800ffc73992c2a68aa78faf47 100644 (file)
@@ -45,9 +45,10 @@ $(TARGET): delete-unfresh-files make-links $(GENERATED_FILES)
 make-links: delete-links
        ln -sf xeno include/linux
        ln -sf asm-$(ARCH) include/asm
+       ln -sf if-$(ARCH) include/hypervisor-ifs/if-arch
 
 delete-links:
-       rm -f include/linux include/asm
+       rm -f include/linux include/asm include/hypervisor-ifs/if-arch
 
 # Blow away kernel.o because build info is stored statically within it.
 delete-unfresh-files:
index 82d459f933e8875e011f0a0155a5d8cebefc5b9c..3b26a5a92bf16e5d6300502dc4478dff0465e2de 100644 (file)
@@ -1,4 +1,4 @@
-ARCH    := i386
+ARCH    ?= i386
 
 TARGET  := $(BASEDIR)/xen
 HDRS    := $(wildcard $(BASEDIR)/include/xeno/*.h)
diff --git a/xen/arch/x86_64/Rules.mk b/xen/arch/x86_64/Rules.mk
new file mode 100644 (file)
index 0000000..56f5932
--- /dev/null
@@ -0,0 +1,17 @@
+########################################
+# x86-specific definitions
+
+CC := gcc
+LD := ld
+# Linker should relocate monitor to this address
+MONITOR_BASE := 0xFC500000
+# Bootloader should load monitor to this real address
+LOAD_BASE    := 0x00100000
+CFLAGS  := -nostdinc -fno-builtin -fno-common -fno-strict-aliasing 
+CFLAGS  += -iwithprefix include -O3 -Wall -DMONITOR_BASE=$(MONITOR_BASE)
+CFLAGS  += -fomit-frame-pointer -I$(BASEDIR)/include -D__KERNEL__ -DNDEBUG
+#CFLAGS  += -fomit-frame-pointer -I$(BASEDIR)/include -D__KERNEL__
+CFLAGS  += -Wno-pointer-arith -Wredundant-decls
+LDFLAGS := -T xeno.lds -N
+
+
diff --git a/xen/include/asm-i386/config.h b/xen/include/asm-i386/config.h
new file mode 100644 (file)
index 0000000..bfd99a0
--- /dev/null
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * config.h
+ * 
+ * A Linux-style configuration list.
+ */
+
+#ifndef __XENO_CONFIG_H__
+#define __XENO_CONFIG_H__
+
+#define CONFIG_X86 1
+
+#define CONFIG_SMP 1
+#define CONFIG_X86_LOCAL_APIC 1
+#define CONFIG_X86_IO_APIC 1
+#define CONFIG_X86_L1_CACHE_SHIFT 5
+
+#define CONFIG_PCI 1
+#define CONFIG_PCI_BIOS 1
+#define CONFIG_PCI_DIRECT 1
+
+#define CONFIG_IDE 1
+#define CONFIG_BLK_DEV_IDE 1
+#define CONFIG_BLK_DEV_IDEDMA 1
+#define CONFIG_BLK_DEV_IDEPCI 1
+#define CONFIG_IDEDISK_MULTI_MODE 1
+#define CONFIG_IDEDISK_STROKE 1
+#define CONFIG_IDEPCI_SHARE_IRQ 1
+#define CONFIG_BLK_DEV_IDEDMA_PCI 1
+#define CONFIG_IDEDMA_PCI_AUTO 1
+#define CONFIG_IDEDMA_AUTO 1
+#define CONFIG_IDEDMA_ONLYDISK 1
+#define CONFIG_BLK_DEV_IDE_MODES 1
+#define CONFIG_BLK_DEV_PIIX 1
+
+#define CONFIG_SCSI 1
+#define CONFIG_SCSI_LOGGING 1
+#define CONFIG_BLK_DEV_SD 1
+#define CONFIG_SD_EXTRA_DEVS 40
+#define CONFIG_SCSI_MULTI_LUN 1
+
+#define CONFIG_XEN_ATTENTION_KEY 1
+
+#define HZ 100
+
+/*
+ * Just to keep compiler happy.
+ * NB. DO NOT CHANGE SMP_CACHE_BYTES WITHOUT FIXING arch/i386/entry.S!!!
+ * It depends on size of irq_cpustat_t, for example, being 64 bytes. :-)
+ * Mmmm... so niiiiiice....
+ */
+#define SMP_CACHE_BYTES 64
+#define NR_CPUS 16
+#define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
+#define ____cacheline_aligned __cacheline_aligned
+
+/*** Hypervisor owns top 64MB of virtual address space. ***/
+#define HYPERVISOR_VIRT_START (0xFC000000UL)
+
+/*
+ * First 4MB are mapped read-only for all. It's for the machine->physical
+ * mapping table (MPT table). The following are virtual addresses.
+ */
+#define READONLY_MPT_VIRT_START (HYPERVISOR_VIRT_START)
+#define READONLY_MPT_VIRT_END   (READONLY_MPT_VIRT_START + (4*1024*1024))
+/*
+ * Next 16MB is fixed monitor space, which is part of a 44MB direct-mapped
+ * memory region. The following are machine addresses.
+ */
+#define MAX_MONITOR_ADDRESS   (16*1024*1024)
+#define MAX_DMA_ADDRESS       (16*1024*1024)
+#define MAX_DIRECTMAP_ADDRESS (44*1024*1024)
+/* And the virtual addresses for the direct-map region... */
+#define DIRECTMAP_VIRT_START  (READONLY_MPT_VIRT_END)
+#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
+#define MONITOR_VIRT_START    (DIRECTMAP_VIRT_START)
+#define MONITOR_VIRT_END      (MONITOR_VIRT_START + MAX_MONITOR_ADDRESS)
+#define RDWR_MPT_VIRT_START   (MONITOR_VIRT_END)
+#define RDWR_MPT_VIRT_END     (RDWR_MPT_VIRT_START + (4*1024*1024))
+#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
+#define FRAMETABLE_VIRT_END   (DIRECTMAP_VIRT_END)
+/* Next 4MB of virtual address space is used as a linear p.t. mapping. */
+#define LINEAR_PT_VIRT_START  (DIRECTMAP_VIRT_END)
+#define LINEAR_PT_VIRT_END    (LINEAR_PT_VIRT_START + (4*1024*1024))
+/* Next 4MB of virtual address space used for per-domain mappings (eg. GDT). */
+#define PERDOMAIN_VIRT_START  (LINEAR_PT_VIRT_END)
+#define PERDOMAIN_VIRT_END    (PERDOMAIN_VIRT_START + (4*1024*1024))
+#define GDT_VIRT_START        (PERDOMAIN_VIRT_START)
+#define GDT_VIRT_END          (GDT_VIRT_START + (64*1024))
+#define LDT_VIRT_START        (GDT_VIRT_END)
+#define LDT_VIRT_END          (LDT_VIRT_START + (64*1024))
+/* Penultimate 4MB of virtual address space used for domain page mappings. */
+#define MAPCACHE_VIRT_START   (PERDOMAIN_VIRT_END)
+#define MAPCACHE_VIRT_END     (MAPCACHE_VIRT_START + (4*1024*1024))
+/* Final 4MB of virtual address space used for ioremap(). */
+#define IOREMAP_VIRT_START    (MAPCACHE_VIRT_END)
+#define IOREMAP_VIRT_END      (IOREMAP_VIRT_START + (4*1024*1024))
+
+/*
+ * Amount of slack domain memory to leave in system, in megabytes.
+ * Prevents a hard out-of-memory crunch for thinsg like network receive.
+ */
+#define SLACK_DOMAIN_MEM_KILOBYTES 2048
+
+/* Linkage for x86 */
+#define FASTCALL(x)     x __attribute__((regparm(3)))
+#define asmlinkage        __attribute__((regparm(0)))
+#define __ALIGN .align 16,0x90
+#define __ALIGN_STR ".align 16,0x90"
+#define SYMBOL_NAME_STR(X) #X
+#define SYMBOL_NAME(X) X
+#define SYMBOL_NAME_LABEL(X) X##:
+#ifdef __ASSEMBLY__
+#define ALIGN __ALIGN
+#define ALIGN_STR __ALIGN_STR
+#define ENTRY(name) \
+  .globl SYMBOL_NAME(name); \
+  ALIGN; \
+  SYMBOL_NAME_LABEL(name)
+#endif
+
+/* syslog levels ==> nothing! */
+#define KERN_NOTICE  ""
+#define KERN_WARNING ""
+#define KERN_DEBUG   ""
+#define KERN_INFO    ""
+#define KERN_ERR     ""
+#define KERN_CRIT    ""
+#define KERN_EMERG   ""
+#define KERN_ALERT   ""
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+#define __HYPERVISOR_CS 0x0808
+#define __HYPERVISOR_DS 0x0810
+
+#define NR_syscalls 256
+
+#define offsetof(_p,_f) ((unsigned long)&(((_p *)0)->_f))
+#define struct_cpy(_x,_y) (memcpy((_x),(_y),sizeof(*(_x))))
+
+#define dev_probe_lock() ((void)0)
+#define dev_probe_unlock() ((void)0)
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define capable(_c) 0
+
+#ifndef NDEBUG
+#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
+                           __FILE__ , __LINE__ , ## _a )
+#define MEMORY_GUARD
+#define TRACE_BUFFER
+#else
+#define DPRINTK(_f, _a...) ((void)0)
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <xeno/compiler.h>
+
+extern unsigned long _end; /* standard ELF symbol */
+extern void __out_of_line_bug(int line) __attribute__((noreturn));
+#define out_of_line_bug() __out_of_line_bug(__LINE__)
+
+extern unsigned int opt_ser_baud;
+#define SERIAL_ENABLED (opt_ser_baud != 0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __XENO_CONFIG_H__ */
diff --git a/xen/include/asm-i386/ldt.h b/xen/include/asm-i386/ldt.h
new file mode 100644 (file)
index 0000000..4da2a15
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __ARCH_LDT_H
+#define __ARCH_LDT_H
+
+#ifndef __ASSEMBLY__
+
+static inline void load_LDT(struct task_struct *p)
+{
+    unsigned int cpu;
+    struct desc_struct *desc;
+    unsigned long ents;
+                                                                                                
+    if ( (ents = p->mm.ldt_ents) == 0 )
+    {
+        __asm__ __volatile__ ( "lldt %%ax" : : "a" (0) );
+    }
+    else
+    {
+        cpu = smp_processor_id();
+        desc = (struct desc_struct *)GET_GDT_ADDRESS(p) + __LDT(cpu);
+        desc->a = ((LDT_VIRT_START&0xffff)<<16) | (ents*8-1);
+        desc->b = (LDT_VIRT_START&(0xff<<24)) | 0x8200 |
+            ((LDT_VIRT_START&0xff0000)>>16);
+        __asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) );
+    }
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/xen/include/asm-x86_64/apic.h b/xen/include/asm-x86_64/apic.h
new file mode 100644 (file)
index 0000000..7059425
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef __ASM_APIC_H
+#define __ASM_APIC_H
+
+#include <linux/config.h>
+#include <asm/ptrace.h>
+#include <asm/apicdef.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+#define APIC_DEBUG 0
+
+#if APIC_DEBUG
+#define Dprintk(x...) printk(x)
+#else
+#define Dprintk(x...)
+#endif
+
+/*
+ * Basic functions accessing APICs.
+ */
+
+static __inline void apic_write(unsigned long reg, unsigned long v)
+{
+       *((volatile unsigned long *)(APIC_BASE+reg)) = v;
+}
+
+static __inline void apic_write_atomic(unsigned long reg, unsigned long v)
+{
+       xchg((volatile unsigned long *)(APIC_BASE+reg), v);
+}
+
+static __inline unsigned long apic_read(unsigned long reg)
+{
+       return *((volatile unsigned long *)(APIC_BASE+reg));
+}
+
+static __inline__ void apic_wait_icr_idle(void)
+{
+       do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
+}
+
+#ifdef CONFIG_X86_GOOD_APIC
+# define FORCE_READ_AROUND_WRITE 0
+# define apic_read_around(x)
+# define apic_write_around(x,y) apic_write((x),(y))
+#else
+# define FORCE_READ_AROUND_WRITE 1
+# define apic_read_around(x) apic_read(x)
+# define apic_write_around(x,y) apic_write_atomic((x),(y))
+#endif
+
+static inline void ack_APIC_irq(void)
+{
+       /*
+        * ack_APIC_irq() actually gets compiled as a single instruction:
+        * - a single rmw on Pentium/82489DX
+        * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC)
+        * ... yummie.
+        */
+
+       /* Docs say use 0 for future compatibility */
+       apic_write_around(APIC_EOI, 0);
+}
+
+extern int get_maxlvt(void);
+extern void connect_bsp_APIC (void);
+extern void disconnect_bsp_APIC (void);
+extern void disable_local_APIC (void);
+extern int verify_local_APIC (void);
+extern void sync_Arb_IDs (void);
+extern void init_bsp_APIC (void);
+extern void setup_local_APIC (void);
+extern void init_apic_mappings (void);
+extern void setup_APIC_clocks (void);
+extern void setup_apic_nmi_watchdog (void);
+extern inline void nmi_watchdog_tick (struct pt_regs * regs);
+extern int APIC_init_uniprocessor (void);
+extern void disable_APIC_timer(void);
+extern void enable_APIC_timer(void);
+
+//extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback);
+//extern void apic_pm_unregister(struct pm_dev*);
+
+extern unsigned int watchdog_on;
+
+extern unsigned int apic_timer_irqs [NR_CPUS];
+extern int check_nmi_watchdog (void);
+
+extern unsigned int nmi_watchdog;
+#define NMI_NONE       0
+#define NMI_IO_APIC    1
+#define NMI_LOCAL_APIC 2
+#define NMI_INVALID    3
+
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+#endif /* __ASM_APIC_H */
diff --git a/xen/include/asm-x86_64/apicdef.h b/xen/include/asm-x86_64/apicdef.h
new file mode 100644 (file)
index 0000000..227bfca
--- /dev/null
@@ -0,0 +1,378 @@
+#ifndef __ASM_APICDEF_H
+#define __ASM_APICDEF_H
+
+/*
+ * Constants for various Intel APICs. (local APIC, IOAPIC, etc.)
+ *
+ * Alan Cox <Alan.Cox@linux.org>, 1995.
+ * Ingo Molnar <mingo@redhat.com>, 1999, 2000
+ */
+
+#define                APIC_DEFAULT_PHYS_BASE  0xfee00000
+#define                APIC_ID         0x20
+#define                        APIC_ID_MASK            (0x0F<<24)
+#define                        GET_APIC_ID(x)          (((x)>>24)&0x0F)
+#define                APIC_LVR        0x30
+#define                        APIC_LVR_MASK           0xFF00FF
+#define                        GET_APIC_VERSION(x)     ((x)&0xFF)
+#define                        GET_APIC_MAXLVT(x)      (((x)>>16)&0xFF)
+#define                        APIC_INTEGRATED(x)      ((x)&0xF0)
+#define                APIC_TASKPRI    0x80
+#define                        APIC_TPRI_MASK          0xFF
+#define                APIC_ARBPRI     0x90
+#define                        APIC_ARBPRI_MASK        0xFF
+#define                APIC_PROCPRI    0xA0
+#define                APIC_EOI        0xB0
+#define                        APIC_EIO_ACK            0x0             /* Write this to the EOI register */
+#define                APIC_RRR        0xC0
+#define                APIC_LDR        0xD0
+#define                        APIC_LDR_MASK           (0xFF<<24)
+#define                        GET_APIC_LOGICAL_ID(x)  (((x)>>24)&0xFF)
+#define                        SET_APIC_LOGICAL_ID(x)  (((x)<<24))
+#define                        APIC_ALL_CPUS           0xFF
+#define                APIC_DFR        0xE0
+#define                        APIC_DFR_CLUSTER        0x0FFFFFFFul    /* Clustered */
+#define                        APIC_DFR_FLAT           0xFFFFFFFFul    /* Flat mode */
+#define                APIC_SPIV       0xF0
+#define                        APIC_SPIV_FOCUS_DISABLED        (1<<9)
+#define                        APIC_SPIV_APIC_ENABLED          (1<<8)
+#define                APIC_ISR        0x100
+#define                APIC_TMR        0x180
+#define        APIC_IRR        0x200
+#define        APIC_ESR        0x280
+#define                        APIC_ESR_SEND_CS        0x00001
+#define                        APIC_ESR_RECV_CS        0x00002
+#define                        APIC_ESR_SEND_ACC       0x00004
+#define                        APIC_ESR_RECV_ACC       0x00008
+#define                        APIC_ESR_SENDILL        0x00020
+#define                        APIC_ESR_RECVILL        0x00040
+#define                        APIC_ESR_ILLREGA        0x00080
+#define                APIC_ICR        0x300
+#define                        APIC_DEST_SELF          0x40000
+#define                        APIC_DEST_ALLINC        0x80000
+#define                        APIC_DEST_ALLBUT        0xC0000
+#define                        APIC_ICR_RR_MASK        0x30000
+#define                        APIC_ICR_RR_INVALID     0x00000
+#define                        APIC_ICR_RR_INPROG      0x10000
+#define                        APIC_ICR_RR_VALID       0x20000
+#define                        APIC_INT_LEVELTRIG      0x08000
+#define                        APIC_INT_ASSERT         0x04000
+#define                        APIC_ICR_BUSY           0x01000
+#define                        APIC_DEST_PHYSICAL      0x00000
+#define                        APIC_DEST_LOGICAL       0x00800
+#define                        APIC_DM_FIXED           0x00000
+#define                        APIC_DM_LOWEST          0x00100
+#define                        APIC_DM_SMI             0x00200
+#define                        APIC_DM_REMRD           0x00300
+#define                        APIC_DM_NMI             0x00400
+#define                        APIC_DM_INIT            0x00500
+#define                        APIC_DM_STARTUP         0x00600
+#define                        APIC_DM_EXTINT          0x00700
+#define                        APIC_VECTOR_MASK        0x000FF
+#define                APIC_ICR2       0x310
+#define                        GET_APIC_DEST_FIELD(x)  (((x)>>24)&0xFF)
+#define                        SET_APIC_DEST_FIELD(x)  ((x)<<24)
+#define                APIC_LVTT       0x320
+#define                APIC_LVTPC      0x340
+#define                APIC_LVT0       0x350
+#define                        APIC_LVT_TIMER_BASE_MASK        (0x3<<18)
+#define                        GET_APIC_TIMER_BASE(x)          (((x)>>18)&0x3)
+#define                        SET_APIC_TIMER_BASE(x)          (((x)<<18))
+#define                        APIC_TIMER_BASE_CLKIN           0x0
+#define                        APIC_TIMER_BASE_TMBASE          0x1
+#define                        APIC_TIMER_BASE_DIV             0x2
+#define                        APIC_LVT_TIMER_PERIODIC         (1<<17)
+#define                        APIC_LVT_MASKED                 (1<<16)
+#define                        APIC_LVT_LEVEL_TRIGGER          (1<<15)
+#define                        APIC_LVT_REMOTE_IRR             (1<<14)
+#define                        APIC_INPUT_POLARITY             (1<<13)
+#define                        APIC_SEND_PENDING               (1<<12)
+#define                        GET_APIC_DELIVERY_MODE(x)       (((x)>>8)&0x7)
+#define                        SET_APIC_DELIVERY_MODE(x,y)     (((x)&~0x700)|((y)<<8))
+#define                                APIC_MODE_FIXED         0x0
+#define                                APIC_MODE_NMI           0x4
+#define                                APIC_MODE_EXINT         0x7
+#define        APIC_LVT1       0x360
+#define                APIC_LVTERR     0x370
+#define                APIC_TMICT      0x380
+#define                APIC_TMCCT      0x390
+#define                APIC_TDCR       0x3E0
+#define                        APIC_TDR_DIV_TMBASE     (1<<2)
+#define                        APIC_TDR_DIV_1          0xB
+#define                        APIC_TDR_DIV_2          0x0
+#define                        APIC_TDR_DIV_4          0x1
+#define                        APIC_TDR_DIV_8          0x2
+#define                        APIC_TDR_DIV_16         0x3
+#define                        APIC_TDR_DIV_32         0x8
+#define                        APIC_TDR_DIV_64         0x9
+#define                        APIC_TDR_DIV_128        0xA
+
+#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
+
+#ifdef CONFIG_X86_CLUSTERED_APIC
+#define MAX_IO_APICS 32
+#else
+#define MAX_IO_APICS 8
+#endif
+
+
+/*
+ * The broadcast ID is 0xF for old APICs and 0xFF for xAPICs.  SAPICs
+ * don't broadcast (yet?), but if they did, they might use 0xFFFF.
+ */
+#define APIC_BROADCAST_ID_XAPIC (0xFF)
+#define APIC_BROADCAST_ID_APIC  (0x0F)
+
+/*
+ * the local APIC register structure, memory mapped. Not terribly well
+ * tested, but we might eventually use this one in the future - the
+ * problem why we cannot use it right now is the P5 APIC, it has an
+ * errata which cannot take 8-bit reads and writes, only 32-bit ones ...
+ */
+#define u32 unsigned int
+
+#define lapic ((volatile struct local_apic *)APIC_BASE)
+
+struct local_apic {
+
+/*000*/        struct { u32 __reserved[4]; } __reserved_01;
+
+/*010*/        struct { u32 __reserved[4]; } __reserved_02;
+
+/*020*/        struct { /* APIC ID Register */
+               u32   __reserved_1      : 24,
+                       phys_apic_id    :  4,
+                       __reserved_2    :  4;
+               u32 __reserved[3];
+       } id;
+
+/*030*/        const
+       struct { /* APIC Version Register */
+               u32   version           :  8,
+                       __reserved_1    :  8,
+                       max_lvt         :  8,
+                       __reserved_2    :  8;
+               u32 __reserved[3];
+       } version;
+
+/*040*/        struct { u32 __reserved[4]; } __reserved_03;
+
+/*050*/        struct { u32 __reserved[4]; } __reserved_04;
+
+/*060*/        struct { u32 __reserved[4]; } __reserved_05;
+
+/*070*/        struct { u32 __reserved[4]; } __reserved_06;
+
+/*080*/        struct { /* Task Priority Register */
+               u32   priority  :  8,
+                       __reserved_1    : 24;
+               u32 __reserved_2[3];
+       } tpr;
+
+/*090*/        const
+       struct { /* Arbitration Priority Register */
+               u32   priority  :  8,
+                       __reserved_1    : 24;
+               u32 __reserved_2[3];
+       } apr;
+
+/*0A0*/        const
+       struct { /* Processor Priority Register */
+               u32   priority  :  8,
+                       __reserved_1    : 24;
+               u32 __reserved_2[3];
+       } ppr;
+
+/*0B0*/        struct { /* End Of Interrupt Register */
+               u32   eoi;
+               u32 __reserved[3];
+       } eoi;
+
+/*0C0*/        struct { u32 __reserved[4]; } __reserved_07;
+
+/*0D0*/        struct { /* Logical Destination Register */
+               u32   __reserved_1      : 24,
+                       logical_dest    :  8;
+               u32 __reserved_2[3];
+       } ldr;
+
+/*0E0*/        struct { /* Destination Format Register */
+               u32   __reserved_1      : 28,
+                       model           :  4;
+               u32 __reserved_2[3];
+       } dfr;
+
+/*0F0*/        struct { /* Spurious Interrupt Vector Register */
+               u32     spurious_vector :  8,
+                       apic_enabled    :  1,
+                       focus_cpu       :  1,
+                       __reserved_2    : 22;
+               u32 __reserved_3[3];
+       } svr;
+
+/*100*/        struct { /* In Service Register */
+/*170*/                u32 bitfield;
+               u32 __reserved[3];
+       } isr [8];
+
+/*180*/        struct { /* Trigger Mode Register */
+/*1F0*/                u32 bitfield;
+               u32 __reserved[3];
+       } tmr [8];
+
+/*200*/        struct { /* Interrupt Request Register */
+/*270*/                u32 bitfield;
+               u32 __reserved[3];
+       } irr [8];
+
+/*280*/        union { /* Error Status Register */
+               struct {
+                       u32   send_cs_error                     :  1,
+                               receive_cs_error                :  1,
+                               send_accept_error               :  1,
+                               receive_accept_error            :  1,
+                               __reserved_1                    :  1,
+                               send_illegal_vector             :  1,
+                               receive_illegal_vector          :  1,
+                               illegal_register_address        :  1,
+                               __reserved_2                    : 24;
+                       u32 __reserved_3[3];
+               } error_bits;
+               struct {
+                       u32 errors;
+                       u32 __reserved_3[3];
+               } all_errors;
+       } esr;
+
+/*290*/        struct { u32 __reserved[4]; } __reserved_08;
+
+/*2A0*/        struct { u32 __reserved[4]; } __reserved_09;
+
+/*2B0*/        struct { u32 __reserved[4]; } __reserved_10;
+
+/*2C0*/        struct { u32 __reserved[4]; } __reserved_11;
+
+/*2D0*/        struct { u32 __reserved[4]; } __reserved_12;
+
+/*2E0*/        struct { u32 __reserved[4]; } __reserved_13;
+
+/*2F0*/        struct { u32 __reserved[4]; } __reserved_14;
+
+/*300*/        struct { /* Interrupt Command Register 1 */
+               u32   vector                    :  8,
+                       delivery_mode           :  3,
+                       destination_mode        :  1,
+                       delivery_status         :  1,
+                       __reserved_1            :  1,
+                       level                   :  1,
+                       trigger                 :  1,
+                       __reserved_2            :  2,
+                       shorthand               :  2,
+                       __reserved_3            :  12;
+               u32 __reserved_4[3];
+       } icr1;
+
+/*310*/        struct { /* Interrupt Command Register 2 */
+               union {
+                       u32   __reserved_1      : 24,
+                               phys_dest       :  4,
+                               __reserved_2    :  4;
+                       u32   __reserved_3      : 24,
+                               logical_dest    :  8;
+               } dest;
+               u32 __reserved_4[3];
+       } icr2;
+
+/*320*/        struct { /* LVT - Timer */
+               u32   vector            :  8,
+                       __reserved_1    :  4,
+                       delivery_status :  1,
+                       __reserved_2    :  3,
+                       mask            :  1,
+                       timer_mode      :  1,
+                       __reserved_3    : 14;
+               u32 __reserved_4[3];
+       } lvt_timer;
+
+/*330*/        struct { u32 __reserved[4]; } __reserved_15;
+
+/*340*/        struct { /* LVT - Performance Counter */
+               u32   vector            :  8,
+                       delivery_mode   :  3,
+                       __reserved_1    :  1,
+                       delivery_status :  1,
+                       __reserved_2    :  3,
+                       mask            :  1,
+                       __reserved_3    : 15;
+               u32 __reserved_4[3];
+       } lvt_pc;
+
+/*350*/        struct { /* LVT - LINT0 */
+               u32   vector            :  8,
+                       delivery_mode   :  3,
+                       __reserved_1    :  1,
+                       delivery_status :  1,
+                       polarity        :  1,
+                       remote_irr      :  1,
+                       trigger         :  1,
+                       mask            :  1,
+                       __reserved_2    : 15;
+               u32 __reserved_3[3];
+       } lvt_lint0;
+
+/*360*/        struct { /* LVT - LINT1 */
+               u32   vector            :  8,
+                       delivery_mode   :  3,
+                       __reserved_1    :  1,
+                       delivery_status :  1,
+                       polarity        :  1,
+                       remote_irr      :  1,
+                       trigger         :  1,
+                       mask            :  1,
+                       __reserved_2    : 15;
+               u32 __reserved_3[3];
+       } lvt_lint1;
+
+/*370*/        struct { /* LVT - Error */
+               u32   vector            :  8,
+                       __reserved_1    :  4,
+                       delivery_status :  1,
+                       __reserved_2    :  3,
+                       mask            :  1,
+                       __reserved_3    : 15;
+               u32 __reserved_4[3];
+       } lvt_error;
+
+/*380*/        struct { /* Timer Initial Count Register */
+               u32   initial_count;
+               u32 __reserved_2[3];
+       } timer_icr;
+
+/*390*/        const
+       struct { /* Timer Current Count Register */
+               u32   curr_count;
+               u32 __reserved_2[3];
+       } timer_ccr;
+
+/*3A0*/        struct { u32 __reserved[4]; } __reserved_16;
+
+/*3B0*/        struct { u32 __reserved[4]; } __reserved_17;
+
+/*3C0*/        struct { u32 __reserved[4]; } __reserved_18;
+
+/*3D0*/        struct { u32 __reserved[4]; } __reserved_19;
+
+/*3E0*/        struct { /* Timer Divide Configuration Register */
+               u32   divisor           :  4,
+                       __reserved_1    : 28;
+               u32 __reserved_2[3];
+       } timer_dcr;
+
+/*3F0*/        struct { u32 __reserved[4]; } __reserved_20;
+
+} __attribute__ ((packed));
+
+#undef u32
+
+#endif
diff --git a/xen/include/asm-x86_64/atomic.h b/xen/include/asm-x86_64/atomic.h
new file mode 100644 (file)
index 0000000..9dcdca9
--- /dev/null
@@ -0,0 +1,195 @@
+#ifndef __ARCH_I386_ATOMIC__
+#define __ARCH_I386_ATOMIC__
+
+#include <xeno/config.h>
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+#ifdef CONFIG_SMP
+#define LOCK "lock ; "
+#else
+#define LOCK ""
+#endif
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically reads the value of @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+#define atomic_read(v)         ((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ * 
+ * Atomically sets the value of @v to @i.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+#define atomic_set(v,i)                (((v)->counter) = (i))
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically adds @i to @v.  Note that the guaranteed useful range
+ * of an atomic_t is only 24 bits.
+ */
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+       __asm__ __volatile__(
+               LOCK "addl %1,%0"
+               :"=m" (v->counter)
+               :"ir" (i), "m" (v->counter));
+}
+
+/**
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically subtracts @i from @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+       __asm__ __volatile__(
+               LOCK "subl %1,%0"
+               :"=m" (v->counter)
+               :"ir" (i), "m" (v->counter));
+}
+
+/**
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
+{
+       unsigned char c;
+
+       __asm__ __volatile__(
+               LOCK "subl %2,%0; sete %1"
+               :"=m" (v->counter), "=qm" (c)
+               :"ir" (i), "m" (v->counter) : "memory");
+       return c;
+}
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically increments @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+static __inline__ void atomic_inc(atomic_t *v)
+{
+       __asm__ __volatile__(
+               LOCK "incl %0"
+               :"=m" (v->counter)
+               :"m" (v->counter));
+}
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically decrements @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+static __inline__ void atomic_dec(atomic_t *v)
+{
+       __asm__ __volatile__(
+               LOCK "decl %0"
+               :"=m" (v->counter)
+               :"m" (v->counter));
+}
+
+/**
+ * atomic_dec_and_test - decrement and test
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+static __inline__ int atomic_dec_and_test(atomic_t *v)
+{
+       unsigned char c;
+
+       __asm__ __volatile__(
+               LOCK "decl %0; sete %1"
+               :"=m" (v->counter), "=qm" (c)
+               :"m" (v->counter) : "memory");
+       return c != 0;
+}
+
+/**
+ * atomic_inc_and_test - increment and test 
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+static __inline__ int atomic_inc_and_test(atomic_t *v)
+{
+       unsigned char c;
+
+       __asm__ __volatile__(
+               LOCK "incl %0; sete %1"
+               :"=m" (v->counter), "=qm" (c)
+               :"m" (v->counter) : "memory");
+       return c != 0;
+}
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ * 
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+static __inline__ int atomic_add_negative(int i, atomic_t *v)
+{
+       unsigned char c;
+
+       __asm__ __volatile__(
+               LOCK "addl %2,%0; sets %1"
+               :"=m" (v->counter), "=qm" (c)
+               :"ir" (i), "m" (v->counter) : "memory");
+       return c;
+}
+
+/* Atomic operations are already serializing on x86 */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec()     barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc()     barrier()
+
+#endif
diff --git a/xen/include/asm-x86_64/bitops.h b/xen/include/asm-x86_64/bitops.h
new file mode 100644 (file)
index 0000000..73bcd8e
--- /dev/null
@@ -0,0 +1,368 @@
+#ifndef _I386_BITOPS_H
+#define _I386_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <xeno/config.h>
+
+/*
+ * These have to be done with inline assembly: that way the bit-setting
+ * is guaranteed to be atomic. All bit operations return 0 if the bit
+ * was cleared before the operation and != 0 if it was not.
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+
+#ifdef CONFIG_SMP
+#define LOCK_PREFIX "lock ; "
+#else
+#define LOCK_PREFIX ""
+#endif
+
+#define ADDR (*(volatile long *) addr)
+
+/**
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is atomic and may not be reordered.  See __set_bit()
+ * if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static __inline__ void set_bit(int nr, volatile void * addr)
+{
+       __asm__ __volatile__( LOCK_PREFIX
+               "btsl %1,%0"
+               :"=m" (ADDR)
+               :"Ir" (nr));
+}
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static __inline__ void __set_bit(int nr, volatile void * addr)
+{
+       __asm__(
+               "btsl %1,%0"
+               :"=m" (ADDR)
+               :"Ir" (nr));
+}
+
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and may not be reordered.  However, it does
+ * not contain a memory barrier, so if it is used for locking purposes,
+ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
+ * in order to ensure changes are visible on other processors.
+ */
+static __inline__ void clear_bit(int nr, volatile void * addr)
+{
+       __asm__ __volatile__( LOCK_PREFIX
+               "btrl %1,%0"
+               :"=m" (ADDR)
+               :"Ir" (nr));
+}
+#define smp_mb__before_clear_bit()     barrier()
+#define smp_mb__after_clear_bit()      barrier()
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+       __asm__ __volatile__(
+               "btcl %1,%0"
+               :"=m" (ADDR)
+               :"Ir" (nr));
+}
+
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * change_bit() is atomic and may not be reordered.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static __inline__ void change_bit(int nr, volatile void * addr)
+{
+       __asm__ __volatile__( LOCK_PREFIX
+               "btcl %1,%0"
+               :"=m" (ADDR)
+               :"Ir" (nr));
+}
+
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+
+       __asm__ __volatile__( LOCK_PREFIX
+               "btsl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit),"=m" (ADDR)
+               :"Ir" (nr) : "memory");
+       return oldbit;
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+
+       __asm__(
+               "btsl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit),"=m" (ADDR)
+               :"Ir" (nr));
+       return oldbit;
+}
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+
+       __asm__ __volatile__( LOCK_PREFIX
+               "btrl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit),"=m" (ADDR)
+               :"Ir" (nr) : "memory");
+       return oldbit;
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+
+       __asm__(
+               "btrl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit),"=m" (ADDR)
+               :"Ir" (nr));
+       return oldbit;
+}
+
+/* WARNING: non atomic and it can be reordered! */
+static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+
+       __asm__ __volatile__(
+               "btcl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit),"=m" (ADDR)
+               :"Ir" (nr) : "memory");
+       return oldbit;
+}
+
+/**
+ * test_and_change_bit - Change a bit and return its new value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+
+       __asm__ __volatile__( LOCK_PREFIX
+               "btcl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit),"=m" (ADDR)
+               :"Ir" (nr) : "memory");
+       return oldbit;
+}
+
+
+static __inline__ int constant_test_bit(int nr, const volatile void * addr)
+{
+       return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+static __inline__ int variable_test_bit(int nr, volatile void * addr)
+{
+       int oldbit;
+
+       __asm__ __volatile__(
+               "btl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit)
+               :"m" (ADDR),"Ir" (nr));
+       return oldbit;
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ constant_test_bit((nr),(addr)) : \
+ variable_test_bit((nr),(addr)))
+
+/**
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first zero bit, not the number of the byte
+ * containing a bit.
+ */
+static __inline__ int find_first_zero_bit(void * addr, unsigned size)
+{
+       int d0, d1, d2;
+       int res;
+
+       if (!size)
+               return 0;
+       /* This looks at memory. Mark it volatile to tell gcc not to move it around */
+       __asm__ __volatile__(
+               "movl $-1,%%eax\n\t"
+               "xorl %%edx,%%edx\n\t"
+               "repe; scasl\n\t"
+               "je 1f\n\t"
+               "xorl -4(%%edi),%%eax\n\t"
+               "subl $4,%%edi\n\t"
+               "bsfl %%eax,%%edx\n"
+               "1:\tsubl %%ebx,%%edi\n\t"
+               "shll $3,%%edi\n\t"
+               "addl %%edi,%%edx"
+               :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+               :"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
+       return res;
+}
+
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+{
+       unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+       int set = 0, bit = offset & 31, res;
+       
+       if (bit) {
+               /*
+                * Look for zero in first byte
+                */
+               __asm__("bsfl %1,%0\n\t"
+                       "jne 1f\n\t"
+                       "movl $32, %0\n"
+                       "1:"
+                       : "=r" (set)
+                       : "r" (~(*p >> bit)));
+               if (set < (32 - bit))
+                       return set + offset;
+               set = 32 - bit;
+               p++;
+       }
+       /*
+        * No zero yet, search remaining full bytes for a zero
+        */
+       res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
+       return (offset + set + res);
+}
+
+/**
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static __inline__ unsigned long ffz(unsigned long word)
+{
+       __asm__("bsfl %1,%0"
+               :"=r" (word)
+               :"r" (~word));
+       return word;
+}
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static __inline__ int ffs(int x)
+{
+       int r;
+
+       __asm__("bsfl %1,%0\n\t"
+               "jnz 1f\n\t"
+               "movl $-1,%0\n"
+               "1:" : "=r" (r) : "g" (x));
+       return r+1;
+}
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
+#define ext2_set_bit                 __test_and_set_bit
+#define ext2_clear_bit               __test_and_clear_bit
+#define ext2_test_bit                test_bit
+#define ext2_find_first_zero_bit     find_first_zero_bit
+#define ext2_find_next_zero_bit      find_next_zero_bit
+
+/* Bitmap functions for the minix filesystem.  */
+#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) __set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif /* _I386_BITOPS_H */
diff --git a/xen/include/asm-x86_64/byteorder.h b/xen/include/asm-x86_64/byteorder.h
new file mode 100644 (file)
index 0000000..bbfb629
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _I386_BYTEORDER_H
+#define _I386_BYTEORDER_H
+
+#include <asm/types.h>
+
+#ifdef __GNUC__
+
+/* For avoiding bswap on i386 */
+#ifdef __KERNEL__
+#include <linux/config.h>
+#endif
+
+static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+{
+#ifdef CONFIG_X86_BSWAP
+       __asm__("bswap %0" : "=r" (x) : "0" (x));
+#else
+       __asm__("xchgb %b0,%h0\n\t"     /* swap lower bytes     */
+               "rorl $16,%0\n\t"       /* swap words           */
+               "xchgb %b0,%h0"         /* swap higher bytes    */
+               :"=q" (x)
+               : "0" (x));
+#endif
+       return x;
+}
+
+static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+{
+       __asm__("xchgb %b0,%h0"         /* swap bytes           */ \
+               : "=q" (x) \
+               :  "0" (x)); \
+               return x;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __GNUC__ */
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _I386_BYTEORDER_H */
diff --git a/xen/include/asm-x86_64/cache.h b/xen/include/asm-x86_64/cache.h
new file mode 100644 (file)
index 0000000..502c8ba
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * include/asm-i386/cache.h
+ */
+#ifndef __ARCH_I386_CACHE_H
+#define __ARCH_I386_CACHE_H
+
+#include <xeno/config.h>
+
+/* L1 cache line size */
+#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#endif
diff --git a/xen/include/asm-x86_64/config.h b/xen/include/asm-x86_64/config.h
new file mode 100644 (file)
index 0000000..bfd99a0
--- /dev/null
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * config.h
+ * 
+ * A Linux-style configuration list.
+ */
+
+#ifndef __XENO_CONFIG_H__
+#define __XENO_CONFIG_H__
+
+#define CONFIG_X86 1
+
+#define CONFIG_SMP 1
+#define CONFIG_X86_LOCAL_APIC 1
+#define CONFIG_X86_IO_APIC 1
+#define CONFIG_X86_L1_CACHE_SHIFT 5
+
+#define CONFIG_PCI 1
+#define CONFIG_PCI_BIOS 1
+#define CONFIG_PCI_DIRECT 1
+
+#define CONFIG_IDE 1
+#define CONFIG_BLK_DEV_IDE 1
+#define CONFIG_BLK_DEV_IDEDMA 1
+#define CONFIG_BLK_DEV_IDEPCI 1
+#define CONFIG_IDEDISK_MULTI_MODE 1
+#define CONFIG_IDEDISK_STROKE 1
+#define CONFIG_IDEPCI_SHARE_IRQ 1
+#define CONFIG_BLK_DEV_IDEDMA_PCI 1
+#define CONFIG_IDEDMA_PCI_AUTO 1
+#define CONFIG_IDEDMA_AUTO 1
+#define CONFIG_IDEDMA_ONLYDISK 1
+#define CONFIG_BLK_DEV_IDE_MODES 1
+#define CONFIG_BLK_DEV_PIIX 1
+
+#define CONFIG_SCSI 1
+#define CONFIG_SCSI_LOGGING 1
+#define CONFIG_BLK_DEV_SD 1
+#define CONFIG_SD_EXTRA_DEVS 40
+#define CONFIG_SCSI_MULTI_LUN 1
+
+#define CONFIG_XEN_ATTENTION_KEY 1
+
+#define HZ 100
+
+/*
+ * Just to keep compiler happy.
+ * NB. DO NOT CHANGE SMP_CACHE_BYTES WITHOUT FIXING arch/i386/entry.S!!!
+ * It depends on size of irq_cpustat_t, for example, being 64 bytes. :-)
+ * Mmmm... so niiiiiice....
+ */
+#define SMP_CACHE_BYTES 64
+#define NR_CPUS 16
+#define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
+#define ____cacheline_aligned __cacheline_aligned
+
+/*** Hypervisor owns top 64MB of virtual address space. ***/
+#define HYPERVISOR_VIRT_START (0xFC000000UL)
+
+/*
+ * First 4MB are mapped read-only for all. It's for the machine->physical
+ * mapping table (MPT table). The following are virtual addresses.
+ */
+#define READONLY_MPT_VIRT_START (HYPERVISOR_VIRT_START)
+#define READONLY_MPT_VIRT_END   (READONLY_MPT_VIRT_START + (4*1024*1024))
+/*
+ * Next 16MB is fixed monitor space, which is part of a 44MB direct-mapped
+ * memory region. The following are machine addresses.
+ */
+#define MAX_MONITOR_ADDRESS   (16*1024*1024)
+#define MAX_DMA_ADDRESS       (16*1024*1024)
+#define MAX_DIRECTMAP_ADDRESS (44*1024*1024)
+/* And the virtual addresses for the direct-map region... */
+#define DIRECTMAP_VIRT_START  (READONLY_MPT_VIRT_END)
+#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
+#define MONITOR_VIRT_START    (DIRECTMAP_VIRT_START)
+#define MONITOR_VIRT_END      (MONITOR_VIRT_START + MAX_MONITOR_ADDRESS)
+#define RDWR_MPT_VIRT_START   (MONITOR_VIRT_END)
+#define RDWR_MPT_VIRT_END     (RDWR_MPT_VIRT_START + (4*1024*1024))
+#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
+#define FRAMETABLE_VIRT_END   (DIRECTMAP_VIRT_END)
+/* Next 4MB of virtual address space is used as a linear p.t. mapping. */
+#define LINEAR_PT_VIRT_START  (DIRECTMAP_VIRT_END)
+#define LINEAR_PT_VIRT_END    (LINEAR_PT_VIRT_START + (4*1024*1024))
+/* Next 4MB of virtual address space used for per-domain mappings (eg. GDT). */
+#define PERDOMAIN_VIRT_START  (LINEAR_PT_VIRT_END)
+#define PERDOMAIN_VIRT_END    (PERDOMAIN_VIRT_START + (4*1024*1024))
+#define GDT_VIRT_START        (PERDOMAIN_VIRT_START)
+#define GDT_VIRT_END          (GDT_VIRT_START + (64*1024))
+#define LDT_VIRT_START        (GDT_VIRT_END)
+#define LDT_VIRT_END          (LDT_VIRT_START + (64*1024))
+/* Penultimate 4MB of virtual address space used for domain page mappings. */
+#define MAPCACHE_VIRT_START   (PERDOMAIN_VIRT_END)
+#define MAPCACHE_VIRT_END     (MAPCACHE_VIRT_START + (4*1024*1024))
+/* Final 4MB of virtual address space used for ioremap(). */
+#define IOREMAP_VIRT_START    (MAPCACHE_VIRT_END)
+#define IOREMAP_VIRT_END      (IOREMAP_VIRT_START + (4*1024*1024))
+
+/*
+ * Amount of slack domain memory to leave in system, in megabytes.
+ * Prevents a hard out-of-memory crunch for thinsg like network receive.
+ */
+#define SLACK_DOMAIN_MEM_KILOBYTES 2048
+
+/* Linkage for x86 */
+#define FASTCALL(x)     x __attribute__((regparm(3)))
+#define asmlinkage        __attribute__((regparm(0)))
+#define __ALIGN .align 16,0x90
+#define __ALIGN_STR ".align 16,0x90"
+#define SYMBOL_NAME_STR(X) #X
+#define SYMBOL_NAME(X) X
+#define SYMBOL_NAME_LABEL(X) X##:
+#ifdef __ASSEMBLY__
+#define ALIGN __ALIGN
+#define ALIGN_STR __ALIGN_STR
+#define ENTRY(name) \
+  .globl SYMBOL_NAME(name); \
+  ALIGN; \
+  SYMBOL_NAME_LABEL(name)
+#endif
+
+/* syslog levels ==> nothing! */
+#define KERN_NOTICE  ""
+#define KERN_WARNING ""
+#define KERN_DEBUG   ""
+#define KERN_INFO    ""
+#define KERN_ERR     ""
+#define KERN_CRIT    ""
+#define KERN_EMERG   ""
+#define KERN_ALERT   ""
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+#define __HYPERVISOR_CS 0x0808
+#define __HYPERVISOR_DS 0x0810
+
+#define NR_syscalls 256
+
+#define offsetof(_p,_f) ((unsigned long)&(((_p *)0)->_f))
+#define struct_cpy(_x,_y) (memcpy((_x),(_y),sizeof(*(_x))))
+
+#define dev_probe_lock() ((void)0)
+#define dev_probe_unlock() ((void)0)
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define capable(_c) 0
+
+#ifndef NDEBUG
+#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
+                           __FILE__ , __LINE__ , ## _a )
+#define MEMORY_GUARD
+#define TRACE_BUFFER
+#else
+#define DPRINTK(_f, _a...) ((void)0)
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <xeno/compiler.h>
+
+extern unsigned long _end; /* standard ELF symbol */
+extern void __out_of_line_bug(int line) __attribute__((noreturn));
+#define out_of_line_bug() __out_of_line_bug(__LINE__)
+
+extern unsigned int opt_ser_baud;
+#define SERIAL_ENABLED (opt_ser_baud != 0)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __XENO_CONFIG_H__ */
diff --git a/xen/include/asm-x86_64/cpufeature.h b/xen/include/asm-x86_64/cpufeature.h
new file mode 100644 (file)
index 0000000..85b8b43
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * cpufeature.h
+ *
+ * Defines x86 CPU feature bits
+ */
+
+#ifndef __ASM_I386_CPUFEATURE_H
+#define __ASM_I386_CPUFEATURE_H
+
+/* Sample usage: CPU_FEATURE_P(cpu.x86_capability, FPU) */
+#define CPU_FEATURE_P(CAP, FEATURE) test_bit(CAP, X86_FEATURE_##FEATURE ##_BIT)
+
+#define NCAPINTS       4       /* Currently we have 4 32-bit words worth of info */
+
+/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
+#define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
+#define X86_FEATURE_VME                (0*32+ 1) /* Virtual Mode Extensions */
+#define X86_FEATURE_DE         (0*32+ 2) /* Debugging Extensions */
+#define X86_FEATURE_PSE        (0*32+ 3) /* Page Size Extensions */
+#define X86_FEATURE_TSC                (0*32+ 4) /* Time Stamp Counter */
+#define X86_FEATURE_MSR                (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
+#define X86_FEATURE_PAE                (0*32+ 6) /* Physical Address Extensions */
+#define X86_FEATURE_MCE                (0*32+ 7) /* Machine Check Architecture */
+#define X86_FEATURE_CX8                (0*32+ 8) /* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC       (0*32+ 9) /* Onboard APIC */
+#define X86_FEATURE_SEP                (0*32+11) /* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR       (0*32+12) /* Memory Type Range Registers */
+#define X86_FEATURE_PGE                (0*32+13) /* Page Global Enable */
+#define X86_FEATURE_MCA                (0*32+14) /* Machine Check Architecture */
+#define X86_FEATURE_CMOV       (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
+#define X86_FEATURE_PAT                (0*32+16) /* Page Attribute Table */
+#define X86_FEATURE_PSE36      (0*32+17) /* 36-bit PSEs */
+#define X86_FEATURE_PN         (0*32+18) /* Processor serial number */
+#define X86_FEATURE_CLFLSH     (0*32+19) /* Supports the CLFLUSH instruction */
+#define X86_FEATURE_DTES       (0*32+21) /* Debug Trace Store */
+#define X86_FEATURE_ACPI       (0*32+22) /* ACPI via MSR */
+#define X86_FEATURE_MMX                (0*32+23) /* Multimedia Extensions */
+#define X86_FEATURE_FXSR       (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
+                                         /* of FPU context), and CR4.OSFXSR available */
+#define X86_FEATURE_XMM                (0*32+25) /* Streaming SIMD Extensions */
+#define X86_FEATURE_XMM2       (0*32+26) /* Streaming SIMD Extensions-2 */
+#define X86_FEATURE_SELFSNOOP  (0*32+27) /* CPU self snoop */
+#define X86_FEATURE_HT         (0*32+28) /* Hyper-Threading */
+#define X86_FEATURE_ACC                (0*32+29) /* Automatic clock control */
+#define X86_FEATURE_IA64       (0*32+30) /* IA-64 processor */
+
+/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+/* Don't duplicate feature flags which are redundant with Intel! */
+#define X86_FEATURE_SYSCALL    (1*32+11) /* SYSCALL/SYSRET */
+#define X86_FEATURE_MMXEXT     (1*32+22) /* AMD MMX extensions */
+#define X86_FEATURE_LM         (1*32+29) /* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT   (1*32+30) /* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW      (1*32+31) /* 3DNow! */
+
+/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
+#define X86_FEATURE_RECOVERY   (2*32+ 0) /* CPU in recovery mode */
+#define X86_FEATURE_LONGRUN    (2*32+ 1) /* Longrun power control */
+#define X86_FEATURE_LRTI       (2*32+ 3) /* LongRun table interface */
+
+/* Other features, Linux-defined mapping, word 3 */
+/* This range is used for feature bits which conflict or are synthesized */
+#define X86_FEATURE_CXMMX      (3*32+ 0) /* Cyrix MMX extensions */
+#define X86_FEATURE_K6_MTRR    (3*32+ 1) /* AMD K6 nonstandard MTRRs */
+#define X86_FEATURE_CYRIX_ARR  (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
+#define X86_FEATURE_CENTAUR_MCR        (3*32+ 3) /* Centaur MCRs (= MTRRs) */
+
+#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
+
+#endif /* __ASM_I386_CPUFEATURE_H */
+
+/* 
+ * Local Variables:
+ * mode:c
+ * comment-column:42
+ * End:
+ */
diff --git a/xen/include/asm-x86_64/current.h b/xen/include/asm-x86_64/current.h
new file mode 100644 (file)
index 0000000..ee5b4b8
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef _I386_CURRENT_H
+#define _I386_CURRENT_H
+
+struct task_struct;
+
+#define STACK_RESERVED \
+    (sizeof(execution_context_t) + sizeof(struct task_struct *))
+
+static inline struct task_struct * get_current(void)
+{
+    struct task_struct *current;
+    __asm__ ( "orl %%esp,%0; andl $~3,%0; movl (%0),%0" 
+              : "=r" (current) : "0" (STACK_SIZE-4) );
+    return current;
+}
+#define current get_current()
+
+static inline void set_current(struct task_struct *p)
+{
+    __asm__ ( "orl %%esp,%0; andl $~3,%0; movl %1,(%0)" 
+              : : "r" (STACK_SIZE-4), "r" (p) );    
+}
+
+static inline execution_context_t *get_execution_context(void)
+{
+    execution_context_t *execution_context;
+    __asm__ ( "andl %%esp,%0; addl %2,%0"
+              : "=r" (execution_context) 
+              : "0" (~(STACK_SIZE-1)), "i" (STACK_SIZE-STACK_RESERVED) );
+    return execution_context;
+}
+
+static inline unsigned long get_stack_top(void)
+{
+    unsigned long p;
+    __asm__ ( "orl %%esp,%0; andl $~3,%0" 
+              : "=r" (p) : "0" (STACK_SIZE-4) );
+    return p;
+}
+
+#define schedule_tail(_p)                                         \
+    __asm__ __volatile__ (                                        \
+        "andl %%esp,%0; addl %2,%0; movl %0,%%esp; jmp *%1"       \
+        : : "r" (~(STACK_SIZE-1)),                                \
+            "r" (unlikely(is_idle_task((_p))) ?                   \
+                                continue_cpu_idle_loop :          \
+                                continue_nonidle_task),           \
+            "i" (STACK_SIZE-STACK_RESERVED) )
+
+
+#endif /* !(_I386_CURRENT_H) */
diff --git a/xen/include/asm-x86_64/debugreg.h b/xen/include/asm-x86_64/debugreg.h
new file mode 100644 (file)
index 0000000..f0b2b06
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef _I386_DEBUGREG_H
+#define _I386_DEBUGREG_H
+
+
+/* Indicate the register numbers for a number of the specific
+   debug registers.  Registers 0-3 contain the addresses we wish to trap on */
+#define DR_FIRSTADDR 0        /* u_debugreg[DR_FIRSTADDR] */
+#define DR_LASTADDR 3         /* u_debugreg[DR_LASTADDR]  */
+
+#define DR_STATUS 6           /* u_debugreg[DR_STATUS]     */
+#define DR_CONTROL 7          /* u_debugreg[DR_CONTROL] */
+
+/* Define a few things for the status register.  We can use this to determine
+   which debugging register was responsible for the trap.  The other bits
+   are either reserved or not of interest to us. */
+
+#define DR_TRAP0       (0x1)           /* db0 */
+#define DR_TRAP1       (0x2)           /* db1 */
+#define DR_TRAP2       (0x4)           /* db2 */
+#define DR_TRAP3       (0x8)           /* db3 */
+
+#define DR_STEP                (0x4000)        /* single-step */
+#define DR_SWITCH      (0x8000)        /* task switch */
+
+/* Now define a bunch of things for manipulating the control register.
+   The top two bytes of the control register consist of 4 fields of 4
+   bits - each field corresponds to one of the four debug registers,
+   and indicates what types of access we trap on, and how large the data
+   field is that we are looking at */
+
+#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */
+#define DR_CONTROL_SIZE 4   /* 4 control bits per register */
+
+#define DR_RW_EXECUTE (0x0)   /* Settings for the access types to trap on */
+#define DR_RW_WRITE (0x1)
+#define DR_RW_READ (0x3)
+
+#define DR_LEN_1 (0x0) /* Settings for data length to trap on */
+#define DR_LEN_2 (0x4)
+#define DR_LEN_4 (0xC)
+
+/* The low byte to the control register determine which registers are
+   enabled.  There are 4 fields of two bits.  One bit is "local", meaning
+   that the processor will reset the bit after a task switch and the other
+   is global meaning that we have to explicitly reset the bit.  With linux,
+   you can use either one, since we explicitly zero the register when we enter
+   kernel mode. */
+
+#define DR_LOCAL_ENABLE_SHIFT 0    /* Extra shift to the local enable bit */
+#define DR_GLOBAL_ENABLE_SHIFT 1   /* Extra shift to the global enable bit */
+#define DR_ENABLE_SIZE 2           /* 2 enable bits per register */
+
+#define DR_LOCAL_ENABLE_MASK (0x55)  /* Set  local bits for all 4 regs */
+#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */
+
+/* The second byte to the control register has a few special things.
+   We can slow the instruction pipeline for instructions coming via the
+   gdt or the ldt if we want to.  I am not sure why this is an advantage */
+
+#define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */
+#define DR_LOCAL_SLOWDOWN (0x100)   /* Local slow the pipeline */
+#define DR_GLOBAL_SLOWDOWN (0x200)  /* Global slow the pipeline */
+
+#endif
diff --git a/xen/include/asm-x86_64/delay.h b/xen/include/asm-x86_64/delay.h
new file mode 100644 (file)
index 0000000..9e0adb4
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _I386_DELAY_H
+#define _I386_DELAY_H
+
+/*
+ * Copyright (C) 1993 Linus Torvalds
+ *
+ * Delay routines calling functions in arch/i386/lib/delay.c
+ */
+
+extern unsigned long ticks_per_usec; 
+extern void __udelay(unsigned long usecs);
+#define udelay(n) __udelay(n)
+
+#endif /* defined(_I386_DELAY_H) */
diff --git a/xen/include/asm-x86_64/desc.h b/xen/include/asm-x86_64/desc.h
new file mode 100644 (file)
index 0000000..780f9c8
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __ARCH_DESC_H
+#define __ARCH_DESC_H
+
+#define LDT_ENTRY_SIZE 8
+
+#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY
+
+#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8)
+#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1)
+
+#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY)
+#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY)
+
+#define load_TR(n)  __asm__ __volatile__ ("ltr  %%ax" : : "a" (__TSS(n)<<3) )
+
+/*
+ * Guest OS must provide its own code selectors, or use the one we provide. The
+ * RPL must be 1, as we only create bounce frames to ring 1. Any LDT selector
+ * value is okay. Note that checking only the RPL is insufficient: if the
+ * selector is poked into an interrupt, trap or call gate then the RPL is
+ * ignored when the gate is accessed.
+ */
+#define VALID_SEL(_s)                                                      \
+    (((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) ||                            \
+      (((_s)>>3) >  LAST_RESERVED_GDT_ENTRY) ||                            \
+      ((_s)&4)) &&                                                         \
+     (((_s)&3) == 1))
+#define VALID_CODESEL(_s) ((_s) == FLAT_RING1_CS || VALID_SEL(_s))
+
+/* These are bitmasks for the first 32 bits of a descriptor table entry. */
+#define _SEGMENT_TYPE    (15<< 8)
+#define _SEGMENT_S       ( 1<<12) /* System descriptor (yes iff S==0) */
+#define _SEGMENT_DPL     ( 3<<13) /* Descriptor Privilege Level */
+#define _SEGMENT_P       ( 1<<15) /* Segment Present */
+#define _SEGMENT_G       ( 1<<23) /* Granularity */
+
+#ifndef __ASSEMBLY__
+struct desc_struct {
+       unsigned long a,b;
+};
+
+extern struct desc_struct gdt_table[];
+extern struct desc_struct *idt, *gdt;
+
+struct Xgt_desc_struct {
+       unsigned short size;
+       unsigned long address __attribute__((packed));
+};
+
+#define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
+#define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
+
+extern void set_intr_gate(unsigned int irq, void * addr);
+extern void set_tss_desc(unsigned int n, void *addr);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/xen/include/asm-x86_64/dma.h b/xen/include/asm-x86_64/dma.h
new file mode 100644 (file)
index 0000000..f24c90a
--- /dev/null
@@ -0,0 +1,301 @@
+/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+#include <linux/config.h>
+#include <linux/spinlock.h>    /* And spinlocks */
+#include <asm/io.h>            /* need byte IO */
+#include <linux/delay.h>
+
+
+#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
+#define dma_outb       outb_p
+#else
+#define dma_outb       outb
+#endif
+
+#define dma_inb                inb
+
+/*
+ * NOTES about DMA transfers:
+ *
+ *  controller 1: channels 0-3, byte operations, ports 00-1F
+ *  controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ *  - ALL registers are 8 bits only, regardless of transfer size
+ *  - channel 4 is not used - cascades 1 into 2.
+ *  - channels 0-3 are byte - addresses/counts are for physical bytes
+ *  - channels 5-7 are word - addresses/counts are for physical words
+ *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ *  - transfer count loaded to registers is 1 less than actual count
+ *  - controller 2 offsets are all even (2x offsets for controller 1)
+ *  - page registers for 5-7 don't use data bit 0, represent 128K pages
+ *  - page registers for 0-3 use bit 0, represent 64K pages
+ *
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.  
+ * Note that addresses loaded into registers must be _physical_ addresses,
+ * not logical addresses (which may differ if paging is active).
+ *
+ *  Address mapping for channels 0-3:
+ *
+ *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *   P7  ...  P0  A7 ... A0  A7 ... A0   
+ * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
+ *
+ *  Address mapping for channels 5-7:
+ *
+ *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
+ *    |  ...  |   \   \   ... \  \  \  ... \  \
+ *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
+ *    |  ...  |     \   \   ... \  \  \  ... \
+ *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
+ * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
+ *
+ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+ * the hardware level, so odd-byte transfers aren't possible).
+ *
+ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+ * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation. 
+ *
+ */
+
+#define MAX_DMA_CHANNELS       8
+
+#if 0
+/* The maximum address that we can perform a DMA transfer to on this platform */
+#define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x1000000)
+#endif
+
+
+/* 8237 DMA controllers */
+#define IO_DMA1_BASE   0x00    /* 8 bit slave DMA, channels 0..3 */
+#define IO_DMA2_BASE   0xC0    /* 16 bit master DMA, ch 4(=slave input)..7 */
+
+/* DMA controller registers */
+#define DMA1_CMD_REG           0x08    /* command register (w) */
+#define DMA1_STAT_REG          0x08    /* status register (r) */
+#define DMA1_REQ_REG            0x09    /* request register (w) */
+#define DMA1_MASK_REG          0x0A    /* single-channel mask (w) */
+#define DMA1_MODE_REG          0x0B    /* mode register (w) */
+#define DMA1_CLEAR_FF_REG      0x0C    /* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
+#define DMA1_RESET_REG         0x0D    /* Master Clear (w) */
+#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
+#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
+
+#define DMA2_CMD_REG           0xD0    /* command register (w) */
+#define DMA2_STAT_REG          0xD0    /* status register (r) */
+#define DMA2_REQ_REG            0xD2    /* request register (w) */
+#define DMA2_MASK_REG          0xD4    /* single-channel mask (w) */
+#define DMA2_MODE_REG          0xD6    /* mode register (w) */
+#define DMA2_CLEAR_FF_REG      0xD8    /* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
+#define DMA2_RESET_REG         0xDA    /* Master Clear (w) */
+#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
+#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
+
+#define DMA_ADDR_0              0x00    /* DMA address registers */
+#define DMA_ADDR_1              0x02
+#define DMA_ADDR_2              0x04
+#define DMA_ADDR_3              0x06
+#define DMA_ADDR_4              0xC0
+#define DMA_ADDR_5              0xC4
+#define DMA_ADDR_6              0xC8
+#define DMA_ADDR_7              0xCC
+
+#define DMA_CNT_0               0x01    /* DMA count registers */
+#define DMA_CNT_1               0x03
+#define DMA_CNT_2               0x05
+#define DMA_CNT_3               0x07
+#define DMA_CNT_4               0xC2
+#define DMA_CNT_5               0xC6
+#define DMA_CNT_6               0xCA
+#define DMA_CNT_7               0xCE
+
+#define DMA_PAGE_0              0x87    /* DMA page registers */
+#define DMA_PAGE_1              0x83
+#define DMA_PAGE_2              0x81
+#define DMA_PAGE_3              0x82
+#define DMA_PAGE_5              0x8B
+#define DMA_PAGE_6              0x89
+#define DMA_PAGE_7              0x8A
+
+#define DMA_MODE_READ  0x44    /* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE 0x48    /* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+#define DMA_AUTOINIT   0x10
+
+
+extern spinlock_t  dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&dma_spin_lock, flags);
+       return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+       spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+       if (dmanr<=3)
+               dma_outb(dmanr,  DMA1_MASK_REG);
+       else
+               dma_outb(dmanr & 3,  DMA2_MASK_REG);
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+       if (dmanr<=3)
+               dma_outb(dmanr | 4,  DMA1_MASK_REG);
+       else
+               dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while holding the DMA lock ! ---
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+       if (dmanr<=3)
+               dma_outb(0,  DMA1_CLEAR_FF_REG);
+       else
+               dma_outb(0,  DMA2_CLEAR_FF_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+       if (dmanr<=3)
+               dma_outb(mode | dmanr,  DMA1_MODE_REG);
+       else
+               dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
+}
+
+/* Set only the page register bits of the transfer address.
+ * This is used for successive transfers when we know the contents of
+ * the lower 16 bits of the DMA current address register, but a 64k boundary
+ * may have been crossed.
+ */
+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+{
+       switch(dmanr) {
+               case 0:
+                       dma_outb(pagenr, DMA_PAGE_0);
+                       break;
+               case 1:
+                       dma_outb(pagenr, DMA_PAGE_1);
+                       break;
+               case 2:
+                       dma_outb(pagenr, DMA_PAGE_2);
+                       break;
+               case 3:
+                       dma_outb(pagenr, DMA_PAGE_3);
+                       break;
+               case 5:
+                       dma_outb(pagenr & 0xfe, DMA_PAGE_5);
+                       break;
+               case 6:
+                       dma_outb(pagenr & 0xfe, DMA_PAGE_6);
+                       break;
+               case 7:
+                       dma_outb(pagenr & 0xfe, DMA_PAGE_7);
+                       break;
+       }
+}
+
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+       set_dma_page(dmanr, a>>16);
+       if (dmanr <= 3)  {
+           dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+       }  else  {
+           dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+           dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+       }
+}
+
+
+/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+        count--;
+       if (dmanr <= 3)  {
+           dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+           dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+        } else {
+           dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+           dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+        }
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+       unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+                                        : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+       /* using short to get 16-bit wrap around */
+       unsigned short count;
+
+       count = 1 + dma_inb(io_port);
+       count += dma_inb(io_port) << 8;
+       
+       return (dmanr<=3)? count : (count<<1);
+}
+
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char * device_id);    /* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);      /* release it again */
+
+/* From PCI */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy   (0)
+#endif
+
+#endif /* _ASM_DMA_H */
diff --git a/xen/include/asm-x86_64/domain_page.h b/xen/include/asm-x86_64/domain_page.h
new file mode 100644 (file)
index 0000000..1d38d8b
--- /dev/null
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * domain_page.h
+ * 
+ * Allow temporary mapping of domain page frames into Xen space.
+ */
+
+#ifndef __ASM_DOMAIN_PAGE_H__
+#define __ASM_DOMAIN_PAGE_H__
+
+#include <xeno/config.h>
+#include <xeno/sched.h>
+
+extern unsigned long *mapcache;
+#define MAPCACHE_ENTRIES        1024
+
+/*
+ * Maps a given physical address, returning corresponding virtual address.
+ * The entire page containing that VA is now accessible until a 
+ * corresponding call to unmap_domain_mem().
+ */
+extern void *map_domain_mem(unsigned long pa);
+
+/*
+ * Pass a VA within a page previously mapped with map_domain_mem().
+ * That page will then be removed from the mapping lists.
+ */
+extern void unmap_domain_mem(void *va);
+
+#endif /* __ASM_DOMAIN_PAGE_H__ */
diff --git a/xen/include/asm-x86_64/elf.h b/xen/include/asm-x86_64/elf.h
new file mode 100644 (file)
index 0000000..ded2285
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1996  Erich Boleyn  <erich@uruk.org>
+ *  Copyright (C) 2001  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* 32-bit data types */
+
+typedef unsigned long Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned long Elf32_Off;
+typedef signed long Elf32_Sword;
+typedef unsigned long Elf32_Word;
+/* "unsigned char" already exists */
+
+/* ELF header */
+typedef struct
+{
+  
+#define EI_NIDENT 16
+  
+  /* first four characters are defined below */
+#define EI_MAG0                0
+#define ELFMAG0                0x7f
+#define EI_MAG1                1
+#define ELFMAG1                'E'
+#define EI_MAG2                2
+#define ELFMAG2                'L'
+#define EI_MAG3                3
+#define ELFMAG3                'F'
+  
+#define EI_CLASS       4       /* data sizes */
+#define ELFCLASS32     1       /* i386 -- up to 32-bit data sizes present */
+  
+#define EI_DATA                5       /* data type and ordering */
+#define ELFDATA2LSB    1       /* i386 -- LSB 2's complement */
+  
+#define EI_VERSION     6       /* version number.  "e_version" must be the same */
+#define EV_CURRENT      1      /* current version number */
+  
+#define EI_PAD         7       /* from here in is just padding */
+  
+#define EI_BRAND       8       /* start of OS branding (This is
+                                  obviously illegal against the ELF
+                                  standard.) */
+  
+  unsigned char e_ident[EI_NIDENT];    /* basic identification block */
+  
+#define ET_EXEC                2       /* we only care about executable types */
+  Elf32_Half e_type;           /* file types */
+  
+#define EM_386         3       /* i386 -- obviously use this one */
+  Elf32_Half e_machine;        /* machine types */
+  Elf32_Word e_version;        /* use same as "EI_VERSION" above */
+  Elf32_Addr e_entry;          /* entry point of the program */
+  Elf32_Off e_phoff;           /* program header table file offset */
+  Elf32_Off e_shoff;           /* section header table file offset */
+  Elf32_Word e_flags;          /* flags */
+  Elf32_Half e_ehsize;         /* elf header size in bytes */
+  Elf32_Half e_phentsize;      /* program header entry size */
+  Elf32_Half e_phnum;          /* number of entries in program header */
+  Elf32_Half e_shentsize;      /* section header entry size */
+  Elf32_Half e_shnum;          /* number of entries in section header */
+  
+#define SHN_UNDEF       0
+#define SHN_LORESERVE   0xff00
+#define SHN_LOPROC      0xff00
+#define SHN_HIPROC      0xff1f
+#define SHN_ABS         0xfff1
+#define SHN_COMMON      0xfff2
+#define SHN_HIRESERVE   0xffff
+  Elf32_Half e_shstrndx;       /* section header table index */
+}
+Elf32_Ehdr;
+
+
+#define BOOTABLE_I386_ELF(h) \
+ ((h.e_ident[EI_MAG0] == ELFMAG0) & (h.e_ident[EI_MAG1] == ELFMAG1) \
+  & (h.e_ident[EI_MAG2] == ELFMAG2) & (h.e_ident[EI_MAG3] == ELFMAG3) \
+  & (h.e_ident[EI_CLASS] == ELFCLASS32) & (h.e_ident[EI_DATA] == ELFDATA2LSB) \
+  & (h.e_ident[EI_VERSION] == EV_CURRENT) & (h.e_type == ET_EXEC) \
+  & (h.e_machine == EM_386) & (h.e_version == EV_CURRENT))
+
+/* section table - ? */
+typedef struct
+{
+  Elf32_Word   sh_name;                /* Section name (string tbl index) */
+  Elf32_Word   sh_type;                /* Section type */
+  Elf32_Word   sh_flags;               /* Section flags */
+  Elf32_Addr   sh_addr;                /* Section virtual addr at execution */
+  Elf32_Off    sh_offset;              /* Section file offset */
+  Elf32_Word   sh_size;                /* Section size in bytes */
+  Elf32_Word   sh_link;                /* Link to another section */
+  Elf32_Word   sh_info;                /* Additional section information */
+  Elf32_Word   sh_addralign;           /* Section alignment */
+  Elf32_Word   sh_entsize;             /* Entry size if section holds table */
+}
+Elf32_Shdr;
+
+/* symbol table - page 4-25, figure 4-15 */
+typedef struct
+{
+  Elf32_Word st_name;
+  Elf32_Addr st_value;
+  Elf32_Word st_size;
+  unsigned char st_info;
+  unsigned char st_other;
+  Elf32_Half st_shndx;
+}
+Elf32_Sym;
+
+/* symbol type and binding attributes - page 4-26 */
+
+#define ELF32_ST_BIND(i)    ((i) >> 4)
+#define ELF32_ST_TYPE(i)    ((i) & 0xf)
+#define ELF32_ST_INFO(b,t)  (((b)<<4)+((t)&0xf))
+
+/* symbol binding - page 4-26, figure 4-16 */
+
+#define STB_LOCAL    0
+#define STB_GLOBAL   1
+#define STB_WEAK     2
+#define STB_LOPROC  13
+#define STB_HIPROC  15
+
+/* symbol types - page 4-28, figure 4-17 */
+
+#define STT_NOTYPE   0
+#define STT_OBJECT   1
+#define STT_FUNC     2
+#define STT_SECTION  3
+#define STT_FILE     4
+#define STT_LOPROC  13
+#define STT_HIPROC  15
+
+
+/* Macros to split/combine relocation type and symbol page 4-32 */
+
+#define ELF32_R_SYM(__i)       ((__i)>>8)
+#define ELF32_R_TYPE(__i)      ((unsigned char) (__i))
+#define ELF32_R_INFO(__s, __t) (((__s)<<8) + (unsigned char) (__t))
+
+
+/* program header - page 5-2, figure 5-1 */
+
+typedef struct
+{
+  Elf32_Word p_type;
+  Elf32_Off p_offset;
+  Elf32_Addr p_vaddr;
+  Elf32_Addr p_paddr;
+  Elf32_Word p_filesz;
+  Elf32_Word p_memsz;
+  Elf32_Word p_flags;
+  Elf32_Word p_align;
+}
+Elf32_Phdr;
+
+/* segment types - page 5-3, figure 5-2 */
+
+#define PT_NULL                0
+#define PT_LOAD                1
+#define PT_DYNAMIC     2
+#define PT_INTERP      3
+#define PT_NOTE                4
+#define PT_SHLIB       5
+#define PT_PHDR                6
+
+#define PT_LOPROC      0x70000000
+#define PT_HIPROC      0x7fffffff
+
+/* segment permissions - page 5-6 */
+
+#define PF_X           0x1
+#define PF_W           0x2
+#define PF_R           0x4
+#define PF_MASKPROC    0xf0000000
+
+
+/* dynamic structure - page 5-15, figure 5-9 */
+
+typedef struct
+{
+  Elf32_Sword d_tag;
+  union
+  {
+    Elf32_Word d_val;
+    Elf32_Addr d_ptr;
+  }
+  d_un;
+}
+Elf32_Dyn;
+
+/* Dynamic array tags - page 5-16, figure 5-10.  */
+
+#define DT_NULL                0
+#define DT_NEEDED      1
+#define DT_PLTRELSZ    2
+#define DT_PLTGOT      3
+#define DT_HASH                4
+#define DT_STRTAB      5
+#define DT_SYMTAB      6
+#define DT_RELA                7
+#define DT_RELASZ      8
+#define DT_RELAENT      9
+#define DT_STRSZ       10
+#define DT_SYMENT      11
+#define DT_INIT                12
+#define DT_FINI                13
+#define DT_SONAME      14
+#define DT_RPATH       15
+#define DT_SYMBOLIC    16
+#define DT_REL         17
+#define DT_RELSZ       18
+#define DT_RELENT      19
+#define DT_PLTREL      20
+#define DT_DEBUG       21
+#define DT_TEXTREL     22
+#define DT_JMPREL      23
diff --git a/xen/include/asm-x86_64/fixmap.h b/xen/include/asm-x86_64/fixmap.h
new file mode 100644 (file)
index 0000000..b0f455a
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * fixmap.h: compile-time virtual memory allocation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Ingo Molnar
+ *
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ */
+
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+#include <xeno/config.h>
+#include <asm/apicdef.h>
+#include <asm/page.h>
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special  addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+
+/*
+ * on UP currently we will have no trace of the fixmap mechanizm,
+ * no page table allocations, etc. This might change in the
+ * future, say framebuffers for the console driver(s) could be
+ * fix-mapped?
+ */
+enum fixed_addresses {
+#ifdef CONFIG_X86_LOCAL_APIC
+       FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
+#endif
+#ifdef CONFIG_X86_IO_APIC
+       FIX_IO_APIC_BASE_0,
+       FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
+#endif
+#ifdef CONFIG_HIGHMEM
+       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#endif
+       __end_of_fixed_addresses
+};
+
+extern void __set_fixmap (enum fixed_addresses idx,
+                          l1_pgentry_t entry);
+
+#define set_fixmap(idx, phys) \
+               __set_fixmap(idx, mk_l1_pgentry(phys|PAGE_HYPERVISOR))
+/*
+ * Some hardware wants to get fixmapped without caching.
+ */
+#define set_fixmap_nocache(idx, phys) \
+               __set_fixmap(idx, mk_l1_pgentry(phys|PAGE_HYPERVISOR_NOCACHE))
+/*
+ * used by vmalloc.c.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap, and leave one page empty
+ * at the top of mem..
+ */
+#define FIXADDR_TOP    (0xffffe000UL)
+#define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+       /*
+        * this branch gets completely eliminated after inlining,
+        * except when someone tries to use fixaddr indices in an
+        * illegal way. (such as mixing up address types or using
+        * out-of-range indices).
+        *
+        * If it doesn't get removed, the linker will complain
+        * loudly with a reasonably clear error message..
+        */
+       if (idx >= __end_of_fixed_addresses)
+               __this_fixmap_does_not_exist();
+
+        return __fix_to_virt(idx);
+}
+
+#endif
diff --git a/xen/include/asm-x86_64/flushtlb.h b/xen/include/asm-x86_64/flushtlb.h
new file mode 100644 (file)
index 0000000..49760ef
--- /dev/null
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * flushtlb.h
+ * 
+ * TLB flushes are timestamped using a global virtual 'clock' which ticks
+ * on any TLB flush on any processor.
+ * 
+ * Copyright (c) 2003, K A Fraser
+ */
+
+#ifndef __FLUSHTLB_H__
+#define __FLUSHTLB_H__
+
+#include <xeno/smp.h>
+
+/*
+ * Every GLOBAL_FLUSH_PERIOD ticks of the tlbflush clock, every TLB in the
+ * system is guaranteed to have been flushed.
+ */
+#define GLOBAL_FLUSH_PERIOD (1<<16)
+
+/*
+ * '_cpu_stamp' is the current timestamp for the CPU we are testing.
+ * '_lastuse_stamp' is a timestamp taken when the PFN we are testing was last 
+ * used for a purpose that may have caused the CPU's TLB to become tainted.
+ */
+#define NEED_FLUSH(_cpu_stamp, _lastuse_stamp) \
+ (((_cpu_stamp) <= (_lastuse_stamp)) &&        \
+  (((_lastuse_stamp) - (_cpu_stamp)) <= (2*GLOBAL_FLUSH_PERIOD)))
+
+extern unsigned long tlbflush_mask;
+extern unsigned long tlbflush_clock;
+extern unsigned long tlbflush_time[NR_CPUS];
+
+extern void new_tlbflush_clock_period(void);
+
+extern void write_cr3_counted(unsigned long pa);
+extern void flush_tlb_counted(void);
+
+#endif /* __FLUSHTLB_H__ */
diff --git a/xen/include/asm-x86_64/hardirq.h b/xen/include/asm-x86_64/hardirq.h
new file mode 100644 (file)
index 0000000..9afe12e
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <xeno/config.h>
+#include <xeno/irq.h>
+
+/* assembly code in softirq.h is sensitive to the offsets of these fields */
+typedef struct {
+       unsigned int __softirq_pending;
+       unsigned int __local_irq_count;
+       unsigned int __local_bh_count;
+       unsigned int __syscall_count;
+       unsigned int __nmi_count;
+       unsigned long idle_timestamp;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <xeno/irq_cpustat.h>  /* Standard mappings for irq_cpustat_t above */
+
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+       (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
+
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+
+#ifndef CONFIG_SMP
+
+#define hardirq_trylock(cpu)   (local_irq_count(cpu) == 0)
+#define hardirq_endlock(cpu)   do { } while (0)
+
+#define irq_enter(cpu, irq)    (local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)     (local_irq_count(cpu)--)
+
+#define synchronize_irq()      barrier()
+
+#else
+
+#include <asm/atomic.h>
+#include <asm/smp.h>
+
+extern unsigned char global_irq_holder;
+extern unsigned volatile long global_irq_lock; /* long for set_bit -RR */
+
+static inline int irqs_running (void)
+{
+       int i;
+
+       for (i = 0; i < smp_num_cpus; i++)
+               if (local_irq_count(i))
+                       return 1;
+       return 0;
+}
+
+static inline void release_irqlock(int cpu)
+{
+       /* if we didn't own the irq lock, just ignore.. */
+       if (global_irq_holder == (unsigned char) cpu) {
+               global_irq_holder = 0xff;
+               clear_bit(0,&global_irq_lock);
+       }
+}
+
+static inline void irq_enter(int cpu, int irq)
+{
+       ++local_irq_count(cpu);
+
+       while (test_bit(0,&global_irq_lock)) {
+               cpu_relax();
+       }
+}
+
+static inline void irq_exit(int cpu, int irq)
+{
+       --local_irq_count(cpu);
+}
+
+static inline int hardirq_trylock(int cpu)
+{
+       return !local_irq_count(cpu) && !test_bit(0,&global_irq_lock);
+}
+
+#define hardirq_endlock(cpu)   do { } while (0)
+
+extern void synchronize_irq(void);
+
+#endif /* CONFIG_SMP */
+
+#endif /* __ASM_HARDIRQ_H */
diff --git a/xen/include/asm-x86_64/hdreg.h b/xen/include/asm-x86_64/hdreg.h
new file mode 100644 (file)
index 0000000..1ad5c07
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ *  linux/include/asm-i386/hdreg.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef __ASMi386_HDREG_H
+#define __ASMi386_HDREG_H
+
+typedef unsigned short ide_ioreg_t;
+
+#endif /* __ASMi386_HDREG_H */
diff --git a/xen/include/asm-x86_64/i387.h b/xen/include/asm-x86_64/i387.h
new file mode 100644 (file)
index 0000000..5a3f0fd
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * include/asm-i386/i387.h
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ *
+ * Pentium III FXSR, SSE support
+ * General FPU state handling cleanups
+ *     Gareth Hughes <gareth@valinux.com>, May 2000
+ */
+
+#ifndef __ASM_I386_I387_H
+#define __ASM_I386_I387_H
+
+#include <xeno/sched.h>
+#include <asm/processor.h>
+
+extern void init_fpu(void);
+extern void save_init_fpu( struct task_struct *tsk );
+extern void restore_fpu( struct task_struct *tsk );
+
+#define unlazy_fpu( tsk ) do { \
+       if ( test_bit(PF_USEDFPU, &tsk->flags) ) \
+               save_init_fpu( tsk ); \
+} while (0)
+
+#define clear_fpu( tsk ) do { \
+       if ( test_and_clear_bit(PF_USEDFPU, &tsk->flags) ) { \
+               asm volatile("fwait"); \
+               stts(); \
+       } \
+} while (0)
+
+#define load_mxcsr( val ) do { \
+        unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
+        asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \
+} while (0)
+
+#endif /* __ASM_I386_I387_H */
diff --git a/xen/include/asm-x86_64/ide.h b/xen/include/asm-x86_64/ide.h
new file mode 100644 (file)
index 0000000..6642abf
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  linux/include/asm-i386/ide.h
+ *
+ *  Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+/*
+ *  This file contains the i386 architecture specific IDE code.
+ */
+
+#ifndef __ASMi386_IDE_H
+#define __ASMi386_IDE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+#ifndef MAX_HWIFS
+# ifdef CONFIG_BLK_DEV_IDEPCI
+#define MAX_HWIFS      10
+# else
+#define MAX_HWIFS      6
+# endif
+#endif
+
+#define ide__sti()     __sti()
+
+static __inline__ int ide_default_irq(ide_ioreg_t base)
+{
+       switch (base) {
+               case 0x1f0: return 14;
+               case 0x170: return 15;
+               case 0x1e8: return 11;
+               case 0x168: return 10;
+               case 0x1e0: return 8;
+               case 0x160: return 12;
+               default:
+                       return 0;
+       }
+}
+
+static __inline__ ide_ioreg_t ide_default_io_base(int index)
+{
+       switch (index) {
+               case 0: return 0x1f0;
+               case 1: return 0x170;
+               case 2: return 0x1e8;
+               case 3: return 0x168;
+               case 4: return 0x1e0;
+               case 5: return 0x160;
+               default:
+                       return 0;
+       }
+}
+
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+{
+       ide_ioreg_t reg = data_port;
+       int i;
+
+       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+               hw->io_ports[i] = reg;
+               reg += 1;
+       }
+       if (ctrl_port) {
+               hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+       } else {
+               hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+       }
+       if (irq != NULL)
+               *irq = 0;
+       hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+static __inline__ void ide_init_default_hwifs(void)
+{
+#ifndef CONFIG_BLK_DEV_IDEPCI
+       hw_regs_t hw;
+       int index;
+
+       for(index = 0; index < MAX_HWIFS; index++) {
+               ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
+               hw.irq = ide_default_irq(ide_default_io_base(index));
+               ide_register_hw(&hw, NULL);
+       }
+#endif /* CONFIG_BLK_DEV_IDEPCI */
+}
+
+typedef union {
+       unsigned all                    : 8;    /* all of the bits together */
+       struct {
+               unsigned head           : 4;    /* always zeros here */
+               unsigned unit           : 1;    /* drive select number, 0 or 1 */
+               unsigned bit5           : 1;    /* always 1 */
+               unsigned lba            : 1;    /* using LBA instead of CHS */
+               unsigned bit7           : 1;    /* always 1 */
+       } b;
+} select_t;
+
+typedef union {
+       unsigned all                    : 8;    /* all of the bits together */
+       struct {
+               unsigned bit0           : 1;
+               unsigned nIEN           : 1;    /* device INTRQ to host */
+               unsigned SRST           : 1;    /* host soft reset bit */
+               unsigned bit3           : 1;    /* ATA-2 thingy */
+               unsigned reserved456    : 3;
+               unsigned HOB            : 1;    /* 48-bit address ordering */
+       } b;
+} control_t;
+
+#define ide_request_irq(irq,hand,flg,dev,id)   request_irq((irq),(hand),(flg),(dev),(id))
+#define ide_free_irq(irq,dev_id)               free_irq((irq), (dev_id))
+#define ide_check_region(from,extent)          check_region((from), (extent))
+#define ide_request_region(from,extent,name)   request_region((from), (extent), (name))
+#define ide_release_region(from,extent)                release_region((from), (extent))
+
+/*
+ * The following are not needed for the non-m68k ports
+ */
+#define ide_ack_intr(hwif)             (1)
+#define ide_fix_driveid(id)            do {} while (0)
+#define ide_release_lock(lock)         do {} while (0)
+#define ide_get_lock(lock, hdlr, data) do {} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMi386_IDE_H */
diff --git a/xen/include/asm-x86_64/io.h b/xen/include/asm-x86_64/io.h
new file mode 100644 (file)
index 0000000..8260e8d
--- /dev/null
@@ -0,0 +1,284 @@
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#include <xeno/config.h>
+#include <asm/page.h>
+
+#define IO_SPACE_LIMIT 0xffff
+
+/*#include <linux/vmalloc.h>*/
+
+/*
+ * Temporary debugging check to catch old code using
+ * unmapped ISA addresses. Will be removed in 2.4.
+ */
+#if CONFIG_DEBUG_IOVIRT
+  extern void *__io_virt_debug(unsigned long x, const char *file, int line);
+  extern unsigned long __io_phys_debug(unsigned long x, const char *file, int line);
+  #define __io_virt(x) __io_virt_debug((unsigned long)(x), __FILE__, __LINE__)
+//#define __io_phys(x) __io_phys_debug((unsigned long)(x), __FILE__, __LINE__)
+#else
+  #define __io_virt(x) ((void *)(x))
+//#define __io_phys(x) __pa(x)
+#endif
+
+
+/**
+ *  virt_to_phys    -   map virtual addresses to physical
+ *  @address: address to remap
+ *
+ *  The returned physical address is the physical (CPU) mapping for
+ *  the memory address given. It is only valid to use this function on
+ *  addresses directly mapped or allocated via kmalloc.
+ *
+ *  This function does not give bus mappings for DMA transfers. In
+ *  almost all conceivable cases a device driver should not be using
+ *  this function
+ */
+
+static inline unsigned long virt_to_phys(volatile void * address)
+{
+    return __pa(address);
+}
+
+/**
+ *  phys_to_virt    -   map physical address to virtual
+ *  @address: address to remap
+ *
+ *  The returned virtual address is a current CPU mapping for
+ *  the memory address given. It is only valid to use this function on
+ *  addresses that have a kernel mapping
+ *
+ *  This function does not handle bus mappings for DMA transfers. In
+ *  almost all conceivable cases a device driver should not be using
+ *  this function
+ */
+
+static inline void * phys_to_virt(unsigned long address)
+{
+    return __va(address);
+}
+
+/*
+ * Change "struct pfn_info" to physical address.
+ */
+#ifdef CONFIG_HIGHMEM64G
+#define page_to_phys(page)  ((u64)(page - frame_table) << PAGE_SHIFT)
+#else
+#define page_to_phys(page)  ((page - frame_table) << PAGE_SHIFT)
+#endif
+
+#define page_to_pfn(_page)  ((unsigned long)((_page) - frame_table))
+#define page_to_virt(_page) phys_to_virt(page_to_phys(_page))
+
+
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+static inline void * ioremap (unsigned long offset, unsigned long size)
+{
+       return __ioremap(offset, size, 0);
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that area.
+ * it's useful if some control registers are in such an area and write combining
+ * or read caching is not desirable:
+ */
+static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
+{
+        return __ioremap(offset, size, _PAGE_PCD);
+}
+
+extern void iounmap(void *addr);
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+#define page_to_bus page_to_phys
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the x86 architecture, we just read/write the
+ * memory location directly.
+ */
+
+#define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
+#define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
+#define readl(addr) (*(volatile unsigned int *) __io_virt(addr))
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+
+#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
+#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
+#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+#define memset_io(a,b,c)       memset(__io_virt(a),(b),(c))
+#define memcpy_fromio(a,b,c)   memcpy((a),__io_virt(b),(c))
+#define memcpy_toio(a,b,c)     memcpy(__io_virt(a),(b),(c))
+
+/*
+ * ISA space is 'always mapped' on a typical x86 system, no need to
+ * explicitly ioremap() it. The fact that the ISA IO space is mapped
+ * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
+ * are physical addresses. The following constant pointer can be
+ * used as the IO-area pointer (it can be iounmapped as well, so the
+ * analogy with PCI is quite large):
+ */
+#define __ISA_IO_base ((char *)(PAGE_OFFSET))
+
+#define isa_readb(a) readb(__ISA_IO_base + (a))
+#define isa_readw(a) readw(__ISA_IO_base + (a))
+#define isa_readl(a) readl(__ISA_IO_base + (a))
+#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
+#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
+#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
+#define isa_memset_io(a,b,c)           memset_io(__ISA_IO_base + (a),(b),(c))
+#define isa_memcpy_fromio(a,b,c)       memcpy_fromio((a),__ISA_IO_base + (b),(c))
+#define isa_memcpy_toio(a,b,c)         memcpy_toio(__ISA_IO_base + (a),(b),(c))
+
+
+/*
+ * Again, i386 does not require mem IO specific function.
+ */
+
+#define eth_io_copy_and_sum(a,b,c,d)           eth_copy_and_sum((a),__io_virt(b),(c),(d))
+#define isa_eth_io_copy_and_sum(a,b,c,d)       eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (b)),(c),(d))
+
+static inline int check_signature(unsigned long io_addr,
+       const unsigned char *signature, int length)
+{
+       int retval = 0;
+       do {
+               if (readb(io_addr) != *signature)
+                       goto out;
+               io_addr++;
+               signature++;
+               length--;
+       } while (length);
+       retval = 1;
+out:
+       return retval;
+}
+
+static inline int isa_check_signature(unsigned long io_addr,
+       const unsigned char *signature, int length)
+{
+       int retval = 0;
+       do {
+               if (isa_readb(io_addr) != *signature)
+                       goto out;
+               io_addr++;
+               signature++;
+               length--;
+       } while (length);
+       retval = 1;
+out:
+       return retval;
+}
+
+/*
+ *     Cache management
+ *
+ *     This needed for two cases
+ *     1. Out of order aware processors
+ *     2. Accidentally out of order processors (PPro errata #51)
+ */
+#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
+
+static inline void flush_write_buffers(void)
+{
+       __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
+}
+
+#define dma_cache_inv(_start,_size)            flush_write_buffers()
+#define dma_cache_wback(_start,_size)          flush_write_buffers()
+#define dma_cache_wback_inv(_start,_size)      flush_write_buffers()
+
+#else
+
+/* Nothing to do */
+
+#define dma_cache_inv(_start,_size)            do { } while (0)
+#define dma_cache_wback(_start,_size)          do { } while (0)
+#define dma_cache_wback_inv(_start,_size)      do { } while (0)
+#define flush_write_buffers()
+
+#endif
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
+#else
+#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
+#endif
+
+#ifdef REALLY_SLOW_IO
+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
+#else
+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+
+/*
+ * Talk about misusing macros..
+ */
+#define __OUT1(s,x) \
+static inline void out##s(unsigned x value, unsigned short port) {
+
+#define __OUT2(s,s1,s2) \
+__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
+
+#define __OUT(s,s1,x) \
+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
+__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} 
+
+#define __IN1(s) \
+static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
+
+#define __IN2(s,s1,s2) \
+__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
+
+#define __IN(s,s1,i...) \
+__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } 
+
+#define __INS(s) \
+static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("rep ; ins" #s \
+: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+#define __OUTS(s) \
+static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("rep ; outs" #s \
+: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+#define RETURN_TYPE unsigned char
+__IN(b,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned short
+__IN(w,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned int
+__IN(l,"")
+#undef RETURN_TYPE
+
+__OUT(b,"b",char)
+__OUT(w,"w",short)
+__OUT(l,,int)
+
+__INS(b)
+__INS(w)
+__INS(l)
+
+__OUTS(b)
+__OUTS(w)
+__OUTS(l)
+
+#endif
diff --git a/xen/include/asm-x86_64/io_apic.h b/xen/include/asm-x86_64/io_apic.h
new file mode 100644 (file)
index 0000000..4491620
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef __ASM_IO_APIC_H
+#define __ASM_IO_APIC_H
+
+#include <xeno/config.h>
+#include <xeno/types.h>
+
+/*
+ * Intel IO-APIC support for SMP and UP systems.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
+ */
+
+#ifdef CONFIG_X86_IO_APIC
+
+#define APIC_MISMATCH_DEBUG
+
+#define IO_APIC_BASE(idx) \
+               ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
+               + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
+
+/*
+ * The structure of the IO-APIC:
+ */
+struct IO_APIC_reg_00 {
+       __u32   __reserved_2    : 24,
+               ID              :  4,
+               __reserved_1    :  4;
+} __attribute__ ((packed));
+
+struct IO_APIC_reg_01 {
+       __u32   version         :  8,
+               __reserved_2    :  7,
+               PRQ             :  1,
+               entries         :  8,
+               __reserved_1    :  8;
+} __attribute__ ((packed));
+
+struct IO_APIC_reg_02 {
+       __u32   __reserved_2    : 24,
+               arbitration     :  4,
+               __reserved_1    :  4;
+} __attribute__ ((packed));
+
+/*
+ * # of IO-APICs and # of IRQ routing registers
+ */
+extern int nr_ioapics;
+extern int nr_ioapic_registers[MAX_IO_APICS];
+
+enum ioapic_irq_destination_types {
+       dest_Fixed = 0,
+       dest_LowestPrio = 1,
+       dest_SMI = 2,
+       dest__reserved_1 = 3,
+       dest_NMI = 4,
+       dest_INIT = 5,
+       dest__reserved_2 = 6,
+       dest_ExtINT = 7
+};
+
+struct IO_APIC_route_entry {
+       __u32   vector          :  8,
+               delivery_mode   :  3,   /* 000: FIXED
+                                        * 001: lowest prio
+                                        * 111: ExtINT
+                                        */
+               dest_mode       :  1,   /* 0: physical, 1: logical */
+               delivery_status :  1,
+               polarity        :  1,
+               irr             :  1,
+               trigger         :  1,   /* 0: edge, 1: level */
+               mask            :  1,   /* 0: enabled, 1: disabled */
+               __reserved_2    : 15;
+
+       union {         struct { __u32
+                                       __reserved_1    : 24,
+                                       physical_dest   :  4,
+                                       __reserved_2    :  4;
+                       } physical;
+
+                       struct { __u32
+                                       __reserved_1    : 24,
+                                       logical_dest    :  8;
+                       } logical;
+       } dest;
+
+} __attribute__ ((packed));
+
+/*
+ * MP-BIOS irq configuration table structures:
+ */
+
+/* I/O APIC entries */
+extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
+
+/* # of MP IRQ source entries */
+extern int mp_irq_entries;
+
+/* MP IRQ source entries */
+extern struct mpc_config_intsrc *mp_irqs;
+
+/* non-0 if default (table-less) MP configuration */
+extern int mpc_default_type;
+
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+       *IO_APIC_BASE(apic) = reg;
+       return *(IO_APIC_BASE(apic)+4);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+       *IO_APIC_BASE(apic) = reg;
+       *(IO_APIC_BASE(apic)+4) = value;
+}
+
+/*
+ * Re-write a value: to be used for read-modify-write
+ * cycles where the read already set up the index register.
+ */
+static inline void io_apic_modify(unsigned int apic, unsigned int value)
+{
+       *(IO_APIC_BASE(apic)+4) = value;
+}
+
+/*
+ * Synchronize the IO-APIC and the CPU by doing
+ * a dummy read from the IO-APIC
+ */
+static inline void io_apic_sync(unsigned int apic)
+{
+       (void) *(IO_APIC_BASE(apic)+4);
+}
+
+/* 1 if "noapic" boot option passed */
+extern int skip_ioapic_setup;
+
+/*
+ * If we use the IO-APIC for IRQ routing, disable automatic
+ * assignment of PCI IRQ's.
+ */
+#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup)
+
+#else  /* !CONFIG_X86_IO_APIC */
+#define io_apic_assign_pci_irqs 0
+#endif
+
+#endif
diff --git a/xen/include/asm-x86_64/ioctl.h b/xen/include/asm-x86_64/ioctl.h
new file mode 100644 (file)
index 0000000..c75f20a
--- /dev/null
@@ -0,0 +1,75 @@
+/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $
+ *
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _ASMI386_IOCTL_H
+#define _ASMI386_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS    8
+#define _IOC_TYPEBITS  8
+#define _IOC_SIZEBITS  14
+#define _IOC_DIRBITS   2
+
+#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT   0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE      0U
+#define _IOC_WRITE     1U
+#define _IOC_READ      2U
+
+#define _IOC(dir,type,nr,size) \
+       (((dir)  << _IOC_DIRSHIFT) | \
+        ((type) << _IOC_TYPESHIFT) | \
+        ((nr)   << _IOC_NRSHIFT) | \
+        ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
+
+#endif /* _ASMI386_IOCTL_H */
diff --git a/xen/include/asm-x86_64/irq.h b/xen/include/asm-x86_64/irq.h
new file mode 100644 (file)
index 0000000..d88429d
--- /dev/null
@@ -0,0 +1,204 @@
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+/* (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar */
+
+#include <xeno/config.h>
+#include <asm/atomic.h>
+
+#define SA_INTERRUPT    0x20000000
+#define SA_SHIRQ        0x04000000
+#define SA_NOPROFILE   0x02000000
+
+#define SA_SAMPLE_RANDOM  0   /* Linux driver compatibility */
+
+#define TIMER_IRQ 0
+
+extern void disable_irq(unsigned int);
+extern void disable_irq_nosync(unsigned int);
+extern void enable_irq(unsigned int);
+
+/*
+ * IDT vectors usable for external interrupt sources start
+ * at 0x20:
+ */
+#define FIRST_EXTERNAL_VECTOR  0x30
+
+#define NR_IRQS (256 - FIRST_EXTERNAL_VECTOR)
+
+#define HYPERVISOR_CALL_VECTOR 0x82
+
+/*
+ * Vectors 0x30-0x3f are used for ISA interrupts.
+ */
+
+/*
+ * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
+ *
+ *  some of the following vectors are 'rare', they are merged
+ *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
+ *  TLB, reschedule and local APIC vectors are performance-critical.
+ *
+ *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
+ */
+#define SPURIOUS_APIC_VECTOR   0xff
+#define ERROR_APIC_VECTOR      0xfe
+#define INVALIDATE_TLB_VECTOR  0xfd
+#define EVENT_CHECK_VECTOR     0xfc
+#define CALL_FUNCTION_VECTOR   0xfb
+#define KDB_VECTOR             0xfa
+
+/*
+ * Local APIC timer IRQ vector is on a different priority level,
+ * to work around the 'lost local interrupt if more than 2 IRQ
+ * sources per level' errata.
+ */
+#define LOCAL_TIMER_VECTOR     0xef
+
+/*
+ * First APIC vector available to drivers: (vectors 0x40-0xee)
+ * we start at 0x41 to spread out vectors evenly between priority
+ * levels. (0x82 is the syscall vector)
+ */
+#define FIRST_DEVICE_VECTOR    0x41
+#define FIRST_SYSTEM_VECTOR    0xef
+
+extern int irq_vector[NR_IRQS];
+#define IO_APIC_VECTOR(irq)    irq_vector[irq]
+
+/*
+ * Various low-level irq details needed by irq.c, process.c,
+ * time.c, io_apic.c and smp.c
+ *
+ * Interrupt entry/exit code at both C and assembly level
+ */
+
+extern void mask_irq(unsigned int irq);
+extern void unmask_irq(unsigned int irq);
+extern void disable_8259A_irq(unsigned int irq);
+extern void enable_8259A_irq(unsigned int irq);
+extern int i8259A_irq_pending(unsigned int irq);
+extern void make_8259A_irq(unsigned int irq);
+extern void init_8259A(int aeoi);
+extern void FASTCALL(send_IPI_self(int vector));
+extern void init_VISWS_APIC_irqs(void);
+extern void setup_IO_APIC(void);
+extern void disable_IO_APIC(void);
+extern void print_IO_APIC(void);
+extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
+extern void send_IPI(int dest, int vector);
+
+extern unsigned long io_apic_irqs;
+
+extern atomic_t irq_err_count;
+extern atomic_t irq_mis_count;
+
+extern char _stext, _etext;
+
+#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
+
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+#define SAVE_ALL \
+       "cld\n\t" \
+       "pushl %gs\n\t" \
+       "pushl %fs\n\t" \
+       "pushl %es\n\t" \
+       "pushl %ds\n\t" \
+       "pushl %eax\n\t" \
+       "pushl %ebp\n\t" \
+       "pushl %edi\n\t" \
+       "pushl %esi\n\t" \
+       "pushl %edx\n\t" \
+       "pushl %ecx\n\t" \
+       "pushl %ebx\n\t" \
+       "movl $" STR(__HYPERVISOR_DS) ",%edx\n\t" \
+       "movl %edx,%ds\n\t" \
+       "movl %edx,%es\n\t" \
+       "movl %edx,%fs\n\t" \
+       "movl %edx,%gs\n\t"
+
+#define IRQ_NAME2(nr) nr##_interrupt(void)
+#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
+
+/*
+ *     SMP has a few special interrupts for IPI messages
+ */
+
+       /* there is a second layer of macro just to get the symbolic
+          name for the vector evaluated. This change is for RTLinux */
+#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
+#define XBUILD_SMP_INTERRUPT(x,v)\
+asmlinkage void x(void); \
+asmlinkage void call_##x(void); \
+__asm__( \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(x) ":\n\t" \
+       "pushl $"#v"-256\n\t" \
+       SAVE_ALL \
+       SYMBOL_NAME_STR(call_##x)":\n\t" \
+       "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
+       "jmp ret_from_intr\n");
+
+#define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v)
+#define XBUILD_SMP_TIMER_INTERRUPT(x,v) \
+asmlinkage void x(struct pt_regs * regs); \
+asmlinkage void call_##x(void); \
+__asm__( \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(x) ":\n\t" \
+       "pushl $"#v"-256\n\t" \
+       SAVE_ALL \
+       "movl %esp,%eax\n\t" \
+       "pushl %eax\n\t" \
+       SYMBOL_NAME_STR(call_##x)":\n\t" \
+       "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
+       "addl $4,%esp\n\t" \
+       "jmp ret_from_intr\n");
+
+#define BUILD_COMMON_IRQ() \
+asmlinkage void call_do_IRQ(void); \
+__asm__( \
+       "\n" __ALIGN_STR"\n" \
+       "common_interrupt:\n\t" \
+       SAVE_ALL \
+       SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \
+       "call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \
+       "jmp ret_from_intr\n");
+
+/* 
+ * subtle. orig_eax is used by the signal code to distinct between
+ * system calls and interrupted 'random user-space'. Thus we have
+ * to put a negative value into orig_eax here. (the problem is that
+ * both system calls and IRQs want to have small integer numbers in
+ * orig_eax, and the syscall code has won the optimization conflict ;)
+ *
+ * Subtle as a pigs ear.  VY
+ */
+
+#define BUILD_IRQ(nr) \
+asmlinkage void IRQ_NAME(nr); \
+__asm__( \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
+       "pushl $"#nr"-256\n\t" \
+       "jmp common_interrupt");
+
+extern unsigned long prof_cpu_mask;
+extern unsigned int * prof_buffer;
+extern unsigned long prof_len;
+extern unsigned long prof_shift;
+
+#include <xeno/irq.h>
+
+#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
+       if (IO_APIC_IRQ(i))
+               send_IPI_self(IO_APIC_VECTOR(i));
+}
+#else
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
+#endif
+
+#endif /* _ASM_HW_IRQ_H */
diff --git a/xen/include/asm-x86_64/ldt.h b/xen/include/asm-x86_64/ldt.h
new file mode 100644 (file)
index 0000000..7a345ce
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __ARCH_LDT_H
+#define __ARCH_LDT_H
+
+#ifndef __ASSEMBLY__
+
+static inline void load_LDT(struct task_struct *p)
+{
+    unsigned long ents;
+
+    if ( (ents = p->mm.ldt_ents) == 0 )
+    {
+        __asm__ __volatile__ ( "lldt %%rax" : : "a" (0) );
+    }
+    else
+    {
+       unsigned int cpu;
+       struct ldttss_desc *desc;
+
+        cpu = smp_processor_id();
+        desc = (struct desc_struct *)((char *)GET_GDT_ADDRESS(p) + __CPU_DESC_INDEX(cpu, ldt));
+       desc->limit0 = ents*8-1;
+       desc->base0 = LDT_VIRT_START&0xffff;
+       desc->base1 = (LDT_VIRT_START&0xff0000)>>16;
+       desc->type = DESC_LDT;
+       desc->dpl = 0;
+       desc->p = 1;
+       desc->limit = 0;
+       desc->zero0 = 0;
+       desc->g = 0;
+       desc->base2 = (LDT_VIRST_START&0xff000000)>>24;
+       desc->base3 = LDT_VIRT_START>>32;
+       desc->zero1 = 0;
+       __load_LDT(cpu);
+    }
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/xen/include/asm-x86_64/mc146818rtc.h b/xen/include/asm-x86_64/mc146818rtc.h
new file mode 100644 (file)
index 0000000..03a4efa
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <asm/io.h>
+#include <xeno/spinlock.h>
+
+extern spinlock_t rtc_lock;             /* serialize CMOS RAM access */
+
+/**********************************************************************
+ * register summary
+ **********************************************************************/
+#define RTC_SECONDS             0
+#define RTC_SECONDS_ALARM       1
+#define RTC_MINUTES             2
+#define RTC_MINUTES_ALARM       3
+#define RTC_HOURS               4
+#define RTC_HOURS_ALARM         5
+/* RTC_*_alarm is always true if 2 MSBs are set */
+# define RTC_ALARM_DONT_CARE    0xC0
+
+#define RTC_DAY_OF_WEEK         6
+#define RTC_DAY_OF_MONTH        7
+#define RTC_MONTH               8
+#define RTC_YEAR                9
+
+/* control registers - Moto names
+ */
+#define RTC_REG_A               10
+#define RTC_REG_B               11
+#define RTC_REG_C               12
+#define RTC_REG_D               13
+
+/**********************************************************************
+ * register details
+ **********************************************************************/
+#define RTC_FREQ_SELECT RTC_REG_A
+
+/* update-in-progress  - set to "1" 244 microsecs before RTC goes off the bus,
+ * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
+ * totalling to a max high interval of 2.228 ms.
+ */
+# define RTC_UIP                0x80
+# define RTC_DIV_CTL            0x70
+   /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
+#  define RTC_REF_CLCK_4MHZ     0x00
+#  define RTC_REF_CLCK_1MHZ     0x10
+#  define RTC_REF_CLCK_32KHZ    0x20
+   /* 2 values for divider stage reset, others for "testing purposes only" */
+#  define RTC_DIV_RESET1        0x60
+#  define RTC_DIV_RESET2        0x70
+  /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
+# define RTC_RATE_SELECT        0x0F
+
+/**********************************************************************/
+#define RTC_CONTROL     RTC_REG_B
+# define RTC_SET 0x80           /* disable updates for clock setting */
+# define RTC_PIE 0x40           /* periodic interrupt enable */
+# define RTC_AIE 0x20           /* alarm interrupt enable */
+# define RTC_UIE 0x10           /* update-finished interrupt enable */
+# define RTC_SQWE 0x08          /* enable square-wave output */
+# define RTC_DM_BINARY 0x04     /* all time/date values are BCD if clear */
+# define RTC_24H 0x02           /* 24 hour mode - else hours bit 7 means pm */
+# define RTC_DST_EN 0x01        /* auto switch DST - works f. USA only */
+
+/**********************************************************************/
+#define RTC_INTR_FLAGS  RTC_REG_C
+/* caution - cleared by read */
+# define RTC_IRQF 0x80          /* any of the following 3 is active */
+# define RTC_PF 0x40
+# define RTC_AF 0x20
+# define RTC_UF 0x10
+
+/**********************************************************************/
+#define RTC_VALID       RTC_REG_D
+# define RTC_VRT 0x80           /* valid RAM and time */
+/**********************************************************************/
+
+/* example: !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) 
+ * determines if the following two #defines are needed
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+
+#ifndef RTC_PORT
+#define RTC_PORT(x)    (0x70 + (x))
+#define RTC_ALWAYS_BCD 1       /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#define RTC_IRQ 8
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/xen/include/asm-x86_64/mpspec.h b/xen/include/asm-x86_64/mpspec.h
new file mode 100644 (file)
index 0000000..7ca70f4
--- /dev/null
@@ -0,0 +1,217 @@
+#ifndef __ASM_MPSPEC_H
+#define __ASM_MPSPEC_H
+
+
+/*
+ * Structure definitions for SMP machines following the
+ * Intel Multiprocessing Specification 1.1 and 1.4.
+ */
+
+/*
+ * This tag identifies where the SMP configuration
+ * information is. 
+ */
+#define SMP_MAGIC_IDENT        (('_'<<24)|('P'<<16)|('M'<<8)|'_')
+
+/*
+ * a maximum of 16 APICs with the current APIC ID architecture.
+ * xAPICs can have up to 256.  SAPICs have 16 ID bits.
+ */
+#ifdef CONFIG_X86_CLUSTERED_APIC
+#define MAX_APICS 256
+#else
+#define MAX_APICS 16
+#endif
+
+#define MAX_MPC_ENTRY 1024
+
+struct intel_mp_floating
+{
+       char mpf_signature[4];          /* "_MP_"                       */
+       unsigned long mpf_physptr;      /* Configuration table address  */
+       unsigned char mpf_length;       /* Our length (paragraphs)      */
+       unsigned char mpf_specification;/* Specification version        */
+       unsigned char mpf_checksum;     /* Checksum (makes sum 0)       */
+       unsigned char mpf_feature1;     /* Standard or configuration ?  */
+       unsigned char mpf_feature2;     /* Bit7 set for IMCR|PIC        */
+       unsigned char mpf_feature3;     /* Unused (0)                   */
+       unsigned char mpf_feature4;     /* Unused (0)                   */
+       unsigned char mpf_feature5;     /* Unused (0)                   */
+};
+
+struct mp_config_table
+{
+       char mpc_signature[4];
+#define MPC_SIGNATURE "PCMP"
+       unsigned short mpc_length;      /* Size of table */
+       char  mpc_spec;                 /* 0x01 */
+       char  mpc_checksum;
+       char  mpc_oem[8];
+       char  mpc_productid[12];
+       unsigned long mpc_oemptr;       /* 0 if not present */
+       unsigned short mpc_oemsize;     /* 0 if not present */
+       unsigned short mpc_oemcount;
+       unsigned long mpc_lapic;        /* APIC address */
+       unsigned long reserved;
+};
+
+/* Followed by entries */
+
+#define        MP_PROCESSOR    0
+#define        MP_BUS          1
+#define        MP_IOAPIC       2
+#define        MP_INTSRC       3
+#define        MP_LINTSRC      4
+#define        MP_TRANSLATION  192  /* Used by IBM NUMA-Q to describe node locality */
+
+struct mpc_config_processor
+{
+       unsigned char mpc_type;
+       unsigned char mpc_apicid;       /* Local APIC number */
+       unsigned char mpc_apicver;      /* Its versions */
+       unsigned char mpc_cpuflag;
+#define CPU_ENABLED            1       /* Processor is available */
+#define CPU_BOOTPROCESSOR      2       /* Processor is the BP */
+       unsigned long mpc_cpufeature;           
+#define CPU_STEPPING_MASK 0x0F
+#define CPU_MODEL_MASK 0xF0
+#define CPU_FAMILY_MASK        0xF00
+       unsigned long mpc_featureflag;  /* CPUID feature value */
+       unsigned long mpc_reserved[2];
+};
+
+struct mpc_config_bus
+{
+       unsigned char mpc_type;
+       unsigned char mpc_busid;
+       unsigned char mpc_bustype[6] __attribute((packed));
+};
+
+/* List of Bus Type string values, Intel MP Spec. */
+#define BUSTYPE_EISA   "EISA"
+#define BUSTYPE_ISA    "ISA"
+#define BUSTYPE_INTERN "INTERN"        /* Internal BUS */
+#define BUSTYPE_MCA    "MCA"
+#define BUSTYPE_VL     "VL"            /* Local bus */
+#define BUSTYPE_PCI    "PCI"
+#define BUSTYPE_PCMCIA "PCMCIA"
+#define BUSTYPE_CBUS   "CBUS"
+#define BUSTYPE_CBUSII "CBUSII"
+#define BUSTYPE_FUTURE "FUTURE"
+#define BUSTYPE_MBI    "MBI"
+#define BUSTYPE_MBII   "MBII"
+#define BUSTYPE_MPI    "MPI"
+#define BUSTYPE_MPSA   "MPSA"
+#define BUSTYPE_NUBUS  "NUBUS"
+#define BUSTYPE_TC     "TC"
+#define BUSTYPE_VME    "VME"
+#define BUSTYPE_XPRESS "XPRESS"
+
+struct mpc_config_ioapic
+{
+       unsigned char mpc_type;
+       unsigned char mpc_apicid;
+       unsigned char mpc_apicver;
+       unsigned char mpc_flags;
+#define MPC_APIC_USABLE                0x01
+       unsigned long mpc_apicaddr;
+};
+
+struct mpc_config_intsrc
+{
+       unsigned char mpc_type;
+       unsigned char mpc_irqtype;
+       unsigned short mpc_irqflag;
+       unsigned char mpc_srcbus;
+       unsigned char mpc_srcbusirq;
+       unsigned char mpc_dstapic;
+       unsigned char mpc_dstirq;
+};
+
+enum mp_irq_source_types {
+       mp_INT = 0,
+       mp_NMI = 1,
+       mp_SMI = 2,
+       mp_ExtINT = 3
+};
+
+#define MP_IRQDIR_DEFAULT      0
+#define MP_IRQDIR_HIGH         1
+#define MP_IRQDIR_LOW          3
+
+
+struct mpc_config_lintsrc
+{
+       unsigned char mpc_type;
+       unsigned char mpc_irqtype;
+       unsigned short mpc_irqflag;
+       unsigned char mpc_srcbusid;
+       unsigned char mpc_srcbusirq;
+       unsigned char mpc_destapic;     
+#define MP_APIC_ALL    0xFF
+       unsigned char mpc_destapiclint;
+};
+
+struct mp_config_oemtable
+{
+       char oem_signature[4];
+#define MPC_OEM_SIGNATURE "_OEM"
+       unsigned short oem_length;      /* Size of table */
+       char  oem_rev;                  /* 0x01 */
+       char  oem_checksum;
+       char  mpc_oem[8];
+};
+
+struct mpc_config_translation
+{
+        unsigned char mpc_type;
+        unsigned char trans_len;
+        unsigned char trans_type;
+        unsigned char trans_quad;
+        unsigned char trans_global;
+        unsigned char trans_local;
+        unsigned short trans_reserved;
+};
+
+/*
+ *     Default configurations
+ *
+ *     1       2 CPU ISA 82489DX
+ *     2       2 CPU EISA 82489DX neither IRQ 0 timer nor IRQ 13 DMA chaining
+ *     3       2 CPU EISA 82489DX
+ *     4       2 CPU MCA 82489DX
+ *     5       2 CPU ISA+PCI
+ *     6       2 CPU EISA+PCI
+ *     7       2 CPU MCA+PCI
+ */
+
+#ifdef CONFIG_MULTIQUAD
+#define MAX_IRQ_SOURCES 512
+#else /* !CONFIG_MULTIQUAD */
+#define MAX_IRQ_SOURCES 256
+#endif /* CONFIG_MULTIQUAD */
+
+#define MAX_MP_BUSSES 32
+enum mp_bustype {
+       MP_BUS_ISA = 1,
+       MP_BUS_EISA,
+       MP_BUS_PCI,
+       MP_BUS_MCA
+};
+extern int *mp_bus_id_to_type;
+extern int *mp_bus_id_to_node;
+extern int *mp_bus_id_to_local;
+extern int *mp_bus_id_to_pci_bus;
+extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
+
+extern unsigned int boot_cpu_physical_apicid;
+extern int smp_found_config;
+extern void find_smp_config (void);
+extern void get_smp_config (void);
+extern int apic_version [MAX_APICS];
+extern int mp_current_pci_id;
+extern unsigned long mp_lapic_addr;
+
+#endif
+
diff --git a/xen/include/asm-x86_64/msr.h b/xen/include/asm-x86_64/msr.h
new file mode 100644 (file)
index 0000000..45ec765
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef __ASM_MSR_H
+#define __ASM_MSR_H
+
+/*
+ * Access to machine-specific registers (available on 586 and better only)
+ * Note: the rd* operations modify the parameters directly (without using
+ * pointer indirection), this allows gcc to optimize better
+ */
+
+#define rdmsr(msr,val1,val2) \
+     __asm__ __volatile__("rdmsr" \
+                         : "=a" (val1), "=d" (val2) \
+                         : "c" (msr))
+
+#define wrmsr(msr,val1,val2) \
+     __asm__ __volatile__("wrmsr" \
+                         : /* no outputs */ \
+                         : "c" (msr), "a" (val1), "d" (val2))
+
+#define rdtsc(low,high) \
+     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
+
+#define rdtscl(low) \
+     __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
+
+#define rdtscll(val) \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+
+#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
+
+#define rdpmc(counter,low,high) \
+     __asm__ __volatile__("rdpmc" \
+                         : "=a" (low), "=d" (high) \
+                         : "c" (counter))
+
+/* symbolic names for some interesting MSRs */
+/* Intel defined MSRs. */
+#define MSR_IA32_P5_MC_ADDR            0
+#define MSR_IA32_P5_MC_TYPE            1
+#define MSR_IA32_PLATFORM_ID           0x17
+#define MSR_IA32_EBL_CR_POWERON                0x2a
+
+#define MSR_IA32_APICBASE              0x1b
+#define MSR_IA32_APICBASE_BSP          (1<<8)
+#define MSR_IA32_APICBASE_ENABLE       (1<<11)
+#define MSR_IA32_APICBASE_BASE         (0xfffff<<12)
+
+#define MSR_IA32_UCODE_WRITE           0x79
+#define MSR_IA32_UCODE_REV             0x8b
+
+#define MSR_IA32_BBL_CR_CTL            0x119
+
+#define MSR_IA32_MCG_CAP               0x179
+#define MSR_IA32_MCG_STATUS            0x17a
+#define MSR_IA32_MCG_CTL               0x17b
+
+#define MSR_IA32_THERM_CONTROL         0x19a
+#define MSR_IA32_THERM_INTERRUPT       0x19b
+#define MSR_IA32_THERM_STATUS          0x19c
+#define MSR_IA32_MISC_ENABLE           0x1a0
+
+#define MSR_IA32_DEBUGCTLMSR           0x1d9
+#define MSR_IA32_LASTBRANCHFROMIP      0x1db
+#define MSR_IA32_LASTBRANCHTOIP                0x1dc
+#define MSR_IA32_LASTINTFROMIP         0x1dd
+#define MSR_IA32_LASTINTTOIP           0x1de
+
+#define MSR_IA32_MC0_CTL               0x400
+#define MSR_IA32_MC0_STATUS            0x401
+#define MSR_IA32_MC0_ADDR              0x402
+#define MSR_IA32_MC0_MISC              0x403
+
+#define MSR_P6_PERFCTR0                        0xc1
+#define MSR_P6_PERFCTR1                        0xc2
+#define MSR_P6_EVNTSEL0                        0x186
+#define MSR_P6_EVNTSEL1                        0x187
+
+/* AMD Defined MSRs */
+#define MSR_K6_EFER                    0xC0000080
+#define MSR_K6_STAR                    0xC0000081
+#define MSR_K6_WHCR                    0xC0000082
+#define MSR_K6_UWCCR                   0xC0000085
+#define MSR_K6_EPMR                    0xC0000086
+#define MSR_K6_PSOR                    0xC0000087
+#define MSR_K6_PFIR                    0xC0000088
+
+#define MSR_K7_EVNTSEL0                        0xC0010000
+#define MSR_K7_PERFCTR0                        0xC0010004
+#define MSR_K7_HWCR                    0xC0010015
+#define MSR_K7_CLK_CTL                 0xC001001b
+#define MSR_K7_FID_VID_CTL             0xC0010041
+#define MSR_K7_VID_STATUS              0xC0010042
+
+/* Centaur-Hauls/IDT defined MSRs. */
+#define MSR_IDT_FCR1                   0x107
+#define MSR_IDT_FCR2                   0x108
+#define MSR_IDT_FCR3                   0x109
+#define MSR_IDT_FCR4                   0x10a
+
+#define MSR_IDT_MCR0                   0x110
+#define MSR_IDT_MCR1                   0x111
+#define MSR_IDT_MCR2                   0x112
+#define MSR_IDT_MCR3                   0x113
+#define MSR_IDT_MCR4                   0x114
+#define MSR_IDT_MCR5                   0x115
+#define MSR_IDT_MCR6                   0x116
+#define MSR_IDT_MCR7                   0x117
+#define MSR_IDT_MCR_CTRL               0x120
+
+/* VIA Cyrix defined MSRs*/
+#define MSR_VIA_FCR                    0x1107
+#define MSR_VIA_LONGHAUL               0x110a
+#define MSR_VIA_BCR2                   0x1147
+
+/* Transmeta defined MSRs */
+#define MSR_TMTA_LONGRUN_CTRL          0x80868010
+#define MSR_TMTA_LONGRUN_FLAGS         0x80868011
+#define MSR_TMTA_LRTI_READOUT          0x80868018
+#define MSR_TMTA_LRTI_VOLT_MHZ         0x8086801a
+
+#endif /* __ASM_MSR_H */
diff --git a/xen/include/asm-x86_64/page.h b/xen/include/asm-x86_64/page.h
new file mode 100644 (file)
index 0000000..a4339d6
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef _I386_PAGE_H
+#define _I386_PAGE_H
+
+#define BUG() do {                                     \
+       printk("BUG at %s:%d\n", __FILE__, __LINE__);   \
+       __asm__ __volatile__("ud2");                    \
+} while (0)
+
+#define L1_PAGETABLE_SHIFT       12
+#define L2_PAGETABLE_SHIFT       22
+
+#define ENTRIES_PER_L1_PAGETABLE 1024
+#define ENTRIES_PER_L2_PAGETABLE 1024
+
+#define PAGE_SHIFT               L1_PAGETABLE_SHIFT
+#define PAGE_SIZE               (1UL << PAGE_SHIFT)
+#define PAGE_MASK               (~(PAGE_SIZE-1))
+
+#define clear_page(_p)           memset((void *)(_p), 0, PAGE_SIZE)
+#define copy_page(_t,_f)         memcpy((void *)(_t), (void *)(_f), PAGE_SIZE)
+
+#ifndef __ASSEMBLY__
+#include <xeno/config.h>
+typedef struct { unsigned long l1_lo; } l1_pgentry_t;
+typedef struct { unsigned long l2_lo; } l2_pgentry_t;
+typedef l1_pgentry_t *l1_pagetable_t;
+typedef l2_pgentry_t *l2_pagetable_t;
+typedef struct { unsigned long pt_lo; } pagetable_t;
+#endif /* !__ASSEMBLY__ */
+
+/* Strip type from a table entry. */
+#define l1_pgentry_val(_x) ((_x).l1_lo)
+#define l2_pgentry_val(_x) ((_x).l2_lo)
+#define pagetable_val(_x)  ((_x).pt_lo)
+
+#define alloc_l1_pagetable()  ((l1_pgentry_t *)get_free_page(GFP_KERNEL))
+#define alloc_l2_pagetable()  ((l2_pgentry_t *)get_free_page(GFP_KERNEL))
+
+/* Add type to a table entry. */
+#define mk_l1_pgentry(_x)  ( (l1_pgentry_t) { (_x) } )
+#define mk_l2_pgentry(_x)  ( (l2_pgentry_t) { (_x) } )
+#define mk_pagetable(_x)   ( (pagetable_t) { (_x) } )
+
+/* Turn a typed table entry into a page index. */
+#define l1_pgentry_to_pagenr(_x) (l1_pgentry_val(_x) >> PAGE_SHIFT) 
+#define l2_pgentry_to_pagenr(_x) (l2_pgentry_val(_x) >> PAGE_SHIFT)
+
+/* Turn a typed table entry into a physical address. */
+#define l1_pgentry_to_phys(_x) (l1_pgentry_val(_x) & PAGE_MASK)
+#define l2_pgentry_to_phys(_x) (l2_pgentry_val(_x) & PAGE_MASK)
+
+/* Dereference a typed level-2 entry to yield a typed level-1 table. */
+#define l2_pgentry_to_l1(_x)     \
+  ((l1_pgentry_t *)__va(l2_pgentry_val(_x) & PAGE_MASK))
+
+/* Given a virtual address, get an entry offset into a page table. */
+#define l1_table_offset(_a) \
+  (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
+#define l2_table_offset(_a) \
+  ((_a) >> L2_PAGETABLE_SHIFT)
+
+/* Hypervisor table entries use zero to sugnify 'empty'. */
+#define l1_pgentry_empty(_x) (!l1_pgentry_val(_x))
+#define l2_pgentry_empty(_x) (!l2_pgentry_val(_x))
+
+#define __PAGE_OFFSET          (0xFC400000)
+#define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
+#define __pa(x)                        ((unsigned long)(x)-PAGE_OFFSET)
+#define __va(x)                        ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define page_address(_p)        (__va(((_p) - frame_table) << PAGE_SHIFT))
+#define virt_to_page(kaddr)    (frame_table + (__pa(kaddr) >> PAGE_SHIFT))
+#define VALID_PAGE(page)       ((page - frame_table) < max_mapnr)
+
+/*
+ * NB. We don't currently track I/O holes in the physical RAM space.
+ * For now we guess that I/O devices will be mapped in the first 1MB
+ * (e.g., VGA buffers) or beyond the end of physical RAM.
+ */
+#define pfn_is_ram(_pfn)        (((_pfn) > 0x100) && ((_pfn) < max_page))
+
+/* High table entries are reserved by the hypervisor. */
+#define DOMAIN_ENTRIES_PER_L2_PAGETABLE            \
+  (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT)
+#define HYPERVISOR_ENTRIES_PER_L2_PAGETABLE \
+  (ENTRIES_PER_L2_PAGETABLE - DOMAIN_ENTRIES_PER_L2_PAGETABLE)
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#include <asm/fixmap.h>
+#include <asm/bitops.h>
+#include <asm/flushtlb.h>
+
+#define linear_pg_table ((l1_pgentry_t *)LINEAR_PT_VIRT_START)
+
+extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
+extern void paging_init(void);
+
+#define __flush_tlb() flush_tlb_counted()
+
+/* Flush global pages as well. */
+
+#define __pge_off()                                                     \
+        do {                                                            \
+                __asm__ __volatile__(                                   \
+                        "movl %0, %%cr4;  # turn off PGE     "          \
+                        :: "r" (mmu_cr4_features & ~X86_CR4_PGE));      \
+        } while (0)
+
+#define __pge_on()                                                      \
+        do {                                                            \
+                __asm__ __volatile__(                                   \
+                        "movl %0, %%cr4;  # turn off PGE     "          \
+                        :: "r" (mmu_cr4_features));                     \
+        } while (0)
+
+
+#define __flush_tlb_pge()                                              \
+       do {                                                            \
+                __pge_off();                                            \
+               flush_tlb_counted();                                    \
+                __pge_on();                                             \
+       } while (0)
+
+#define __flush_tlb_one(__addr) \
+__asm__ __volatile__("invlpg %0": :"m" (*(char *) (__addr)))
+
+#endif /* !__ASSEMBLY__ */
+
+
+#define _PAGE_PRESENT  0x001
+#define _PAGE_RW       0x002
+#define _PAGE_USER     0x004
+#define _PAGE_PWT      0x008
+#define _PAGE_PCD      0x010
+#define _PAGE_ACCESSED 0x020
+#define _PAGE_DIRTY    0x040
+#define _PAGE_PAT       0x080
+#define _PAGE_PSE      0x080
+#define _PAGE_GLOBAL   0x100
+
+#define __PAGE_HYPERVISOR \
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define __PAGE_HYPERVISOR_NOCACHE \
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED)
+#define __PAGE_HYPERVISOR_RO \
+       (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
+
+#define MAKE_GLOBAL(_x) ((_x) | _PAGE_GLOBAL)
+
+#define PAGE_HYPERVISOR MAKE_GLOBAL(__PAGE_HYPERVISOR)
+#define PAGE_HYPERVISOR_RO MAKE_GLOBAL(__PAGE_HYPERVISOR_RO)
+#define PAGE_HYPERVISOR_NOCACHE MAKE_GLOBAL(__PAGE_HYPERVISOR_NOCACHE)
+
+#define mk_l2_writeable(_p) \
+    (*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) |  _PAGE_RW))
+#define mk_l2_readonly(_p) \
+    (*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) & ~_PAGE_RW))
+#define mk_l1_writeable(_p) \
+    (*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) |  _PAGE_RW))
+#define mk_l1_readonly(_p) \
+    (*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) & ~_PAGE_RW))
+
+
+#ifndef __ASSEMBLY__
+static __inline__ int get_order(unsigned long size)
+{
+    int order;
+    
+    size = (size-1) >> (PAGE_SHIFT-1);
+    order = -1;
+    do {
+        size >>= 1;
+        order++;
+    } while (size);
+    return order;
+}
+#endif
+
+#endif /* _I386_PAGE_H */
diff --git a/xen/include/asm-x86_64/param.h b/xen/include/asm-x86_64/param.h
new file mode 100644 (file)
index 0000000..1b10bf4
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _ASMi386_PARAM_H
+#define _ASMi386_PARAM_H
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE  4096
+
+#ifndef NGROUPS
+#define NGROUPS                32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP                (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64      /* max length of hostname */
+
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC        100     /* frequency at which times() counts */
+#endif
+
+#endif
diff --git a/xen/include/asm-x86_64/pci.h b/xen/include/asm-x86_64/pci.h
new file mode 100644 (file)
index 0000000..a38bef4
--- /dev/null
@@ -0,0 +1,286 @@
+#ifndef __i386_PCI_H
+#define __i386_PCI_H
+
+#include <linux/config.h>
+
+#ifdef __KERNEL__
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+   already-configured bus numbers - to be used for buggy BIOSes
+   or architectures with incomplete PCI setup by the loader */
+
+#ifdef CONFIG_PCI
+extern unsigned int pcibios_assign_all_busses(void);
+#else
+#define pcibios_assign_all_busses()    0
+#endif
+
+extern unsigned long pci_mem_start;
+#define PCIBIOS_MIN_IO         0x1000
+#define PCIBIOS_MIN_MEM                (pci_mem_start)
+
+void pcibios_set_master(struct pci_dev *dev);
+void pcibios_penalize_isa_irq(int irq);
+struct irq_routing_table *pcibios_get_irq_routing_table(void);
+int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
+
+/* Dynamic DMA mapping stuff.
+ * i386 has everything mapped statically.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+/*#include <linux/string.h>*/
+#include <asm/io.h>
+
+struct pci_dev;
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS    (1)
+
+/* Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+                                 dma_addr_t *dma_handle);
+
+/* Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+                               void *vaddr, dma_addr_t dma_handle);
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+                                       size_t size, int direction)
+{
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+       flush_write_buffers();
+       return virt_to_bus(ptr);
+}
+
+/* Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+                                   size_t size, int direction)
+{
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+       /* Nothing to do */
+}
+
+/*
+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct pfn_info instead of a virtual address
+ */
+static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct pfn_info *page,
+                                     unsigned long offset, size_t size, int direction)
+{
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+
+       return (dma_addr_t)(page - frame_table) * PAGE_SIZE + offset;
+}
+
+static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
+                                 size_t size, int direction)
+{
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+       /* Nothing to do */
+}
+
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)         (0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)        do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)           (0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
+
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+                            int nents, int direction)
+{
+       int i;
+
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+       /*
+        * temporary 2.4 hack
+        */
+       for (i = 0; i < nents; i++ ) {
+               if (sg[i].address && sg[i].page)
+                       out_of_line_bug();
+#if 0
+               /* Invalid check, since address==0 is valid. */
+               else if (!sg[i].address && !sg[i].page)
+                       out_of_line_bug();
+#endif
+               /* XXX Switched round, since address==0 is valid. */
+               if (sg[i].page)
+                       sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
+               else
+                       sg[i].dma_address = virt_to_bus(sg[i].address);
+       }
+       flush_write_buffers();
+       return nents;
+}
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+                               int nents, int direction)
+{
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+       /* Nothing to do */
+}
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
+                                      dma_addr_t dma_handle,
+                                      size_t size, int direction)
+{
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+       flush_write_buffers();
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+                                  struct scatterlist *sg,
+                                  int nelems, int direction)
+{
+       if (direction == PCI_DMA_NONE)
+               out_of_line_bug();
+       flush_write_buffers();
+}
+
+/* Return whether the given PCI device DMA address mask can
+ * be supported properly.  For example, if your device can
+ * only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if(mask < 0x00ffffff)
+                return 0;
+
+       return 1;
+}
+
+/* This is always fine. */
+#define pci_dac_dma_supported(pci_dev, mask)   (1)
+
+static __inline__ dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct pfn_info *page, unsigned long offset, int direction)
+{
+       return ((dma64_addr_t) page_to_bus(page) +
+               (dma64_addr_t) offset);
+}
+
+static __inline__ struct pfn_info *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+       unsigned long poff = (dma_addr >> PAGE_SHIFT);
+
+       return frame_table + poff;
+}
+
+static __inline__ unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+       return (dma_addr & ~PAGE_MASK);
+}
+
+static __inline__ void
+pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
+{
+       flush_write_buffers();
+}
+
+/* These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns.
+ */
+#define sg_dma_address(sg)     ((sg)->dma_address)
+#define sg_dma_len(sg)         ((sg)->length)
+
+/* Return the index of the PCI controller for device. */
+static inline int pci_controller_num(struct pci_dev *dev)
+{
+       return 0;
+}
+
+#if 0 /* XXX Not in land of Xen XXX */
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+                              enum pci_mmap_state mmap_state, int write_combine);
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __i386_PCI_H */
diff --git a/xen/include/asm-x86_64/pda.h b/xen/include/asm-x86_64/pda.h
new file mode 100644 (file)
index 0000000..a2223a5
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef X86_64_PDA_H
+#define X86_64_PDA_H
+
+#include <linux/cache.h>
+
+/* Per processor datastructure. %gs points to it while the kernel runs */ 
+/* To use a new field with the *_pda macros it needs to be added to tools/offset.c */
+struct x8664_pda {
+       unsigned long kernelstack;  /* TOS for current process */ 
+       unsigned long oldrsp;       /* user rsp for system call */
+       unsigned long irqrsp;       /* Old rsp for interrupts. */ 
+       struct task_struct *pcurrent;   /* Current process */
+        int irqcount;              /* Irq nesting counter. Starts with -1 */   
+       int cpunumber;              /* Logical CPU number */
+       /* XXX: could be a single list */
+       unsigned long *pgd_quick;
+       unsigned long *pmd_quick;
+       unsigned long *pte_quick;
+       unsigned long pgtable_cache_sz;
+       char *irqstackptr;      /* top of irqstack */
+       unsigned long volatile *level4_pgt; 
+} ____cacheline_aligned;
+
+#define PDA_STACKOFFSET (5*8)
+
+#define IRQSTACK_ORDER 2
+#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) 
+
+extern struct x8664_pda cpu_pda[];
+
+/* 
+ * There is no fast way to get the base address of the PDA, all the accesses
+ * have to mention %fs/%gs.  So it needs to be done this Torvaldian way.
+ */ 
+#define sizeof_field(type,field)  (sizeof(((type *)0)->field))
+#define typeof_field(type,field)  typeof(((type *)0)->field)
+
+extern void __bad_pda_field(void);
+/* Don't use offsetof because it requires too much infrastructure */
+#define pda_offset(field) ((unsigned long)&((struct x8664_pda *)0)->field)
+
+#define pda_to_op(op,field,val) do { \
+       switch (sizeof_field(struct x8664_pda, field)) {                \
+       case 2: asm volatile(op "w %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;  \
+       case 4: asm volatile(op "l %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;  \
+       case 8: asm volatile(op "q %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break;  \
+       default: __bad_pda_field();                                     \
+       } \
+       } while (0)
+
+
+#define pda_from_op(op,field) ({ \
+       typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \
+       switch (sizeof_field(struct x8664_pda, field)) {                \
+       case 2: asm volatile(op "w %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \
+       case 4: asm volatile(op "l %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \
+       case 8: asm volatile(op "q %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \
+       default: __bad_pda_field();                                     \
+       } \
+       ret__; })
+
+
+#define read_pda(field) pda_from_op("mov",field)
+#define write_pda(field,val) pda_to_op("mov",field,val)
+#define add_pda(field,val) pda_to_op("add",field,val)
+#define sub_pda(field,val) pda_to_op("sub",field,val)
+
+#endif
diff --git a/xen/include/asm-x86_64/pdb.h b/xen/include/asm-x86_64/pdb.h
new file mode 100644 (file)
index 0000000..fa161f2
--- /dev/null
@@ -0,0 +1,51 @@
+
+/*
+ * pervasive debugger
+ *
+ * alex ho
+ * 2004
+ * university of cambridge computer laboratory
+ */
+
+
+#ifndef __PDB_H__
+#define __PDB_H__
+
+#include <asm/ptrace.h>
+#include <xeno/list.h>
+
+extern int pdb_initialized;
+extern int pdb_com_port;
+extern int pdb_high_bit;
+
+extern void initialize_pdb(void);
+
+/* Get/set values from generic debug interface. */
+extern int pdb_set_values(domid_t domain, u_char *buffer, 
+                          unsigned long addr, int length);
+extern int pdb_get_values(domid_t domain, u_char *buffer,
+                          unsigned long addr, int length);
+
+/* External entry points. */
+extern int pdb_handle_exception(int exceptionVector,
+                               struct pt_regs *xen_regs);
+extern int pdb_serial_input(u_char c, struct pt_regs *regs);
+extern void pdb_do_debug(dom0_op_t *op);
+
+/* Breakpoints. */
+struct pdb_breakpoint
+{
+    struct list_head list;
+    unsigned long address;
+};
+extern void pdb_bkpt_add (unsigned long address);
+extern struct pdb_breakpoint* pdb_bkpt_search (unsigned long address);
+extern int pdb_bkpt_remove (unsigned long address);
+
+/* Conversions. */
+extern int   hex (char);
+extern char *mem2hex (char *, char *, int);
+extern char *hex2mem (char *, char *, int);
+extern int   hexToInt (char **ptr, int *intValue);
+
+#endif  /* __PDB_H__ */
diff --git a/xen/include/asm-x86_64/pgalloc.h b/xen/include/asm-x86_64/pgalloc.h
new file mode 100644 (file)
index 0000000..6f01b44
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef _I386_PGALLOC_H
+#define _I386_PGALLOC_H
+
+#include <xeno/config.h>
+#include <xeno/sched.h>
+#include <asm/processor.h>
+#include <asm/fixmap.h>
+
+#define pgd_quicklist (current_cpu_data.pgd_quick)
+#define pmd_quicklist (current_cpu_data.pmd_quick)
+#define pte_quicklist (current_cpu_data.pte_quick)
+#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
+
+
+/*
+ * Allocate and free page tables.
+ */
+
+
+#define pte_free(pte)          pte_free_fast(pte)
+#define pgd_alloc(mm)          get_pgd_fast()
+#define pgd_free(pgd)          free_pgd_fast(pgd)
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ * (In the PAE case we free the pmds as part of the pgd.)
+ */
+
+#define pmd_alloc_one_fast(mm, addr)   ({ BUG(); ((pmd_t *)1); })
+#define pmd_alloc_one(mm, addr)                ({ BUG(); ((pmd_t *)2); })
+#define pmd_free_slow(x)               do { } while (0)
+#define pmd_free_fast(x)               do { } while (0)
+#define pmd_free(x)                    do { } while (0)
+#define pgd_populate(mm, pmd, pte)     BUG()
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb() flushes the current mm struct TLBs
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ *
+ * ..but the i386 has somewhat limited tlb flushing capabilities,
+ * and page-granular flushes are available only on i486 and up.
+ */
+
+#ifndef CONFIG_SMP
+
+#define flush_tlb()               __flush_tlb()
+#define flush_tlb_all()           __flush_tlb()
+#define flush_tlb_all_pge()       __flush_tlb_pge()
+#define local_flush_tlb()         __flush_tlb()
+#define flush_tlb_cpu(_cpu)       __flush_tlb()
+#define flush_tlb_mask(_mask)     __flush_tlb()
+#define try_flush_tlb_mask(_mask) __flush_tlb()
+
+#else
+
+#include <xeno/smp.h>
+
+extern int try_flush_tlb_mask(unsigned long mask);
+extern void flush_tlb_mask(unsigned long mask);
+extern void flush_tlb_all_pge(void);
+
+#define flush_tlb()        __flush_tlb()
+#define flush_tlb_all()     flush_tlb_mask((1 << smp_num_cpus) - 1)
+#define local_flush_tlb()   __flush_tlb()
+#define flush_tlb_cpu(_cpu) flush_tlb_mask(1 << (_cpu))
+
+#endif
+
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                     unsigned long start, unsigned long end)
+{
+       /* i386 does not keep any page table caches in TLB */
+}
+
+#endif /* _I386_PGALLOC_H */
diff --git a/xen/include/asm-x86_64/processor.h b/xen/include/asm-x86_64/processor.h
new file mode 100644 (file)
index 0000000..c7df85a
--- /dev/null
@@ -0,0 +1,493 @@
+/*
+ * include/asm-i386/processor.h
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ */
+
+#ifndef __ASM_I386_PROCESSOR_H
+#define __ASM_I386_PROCESSOR_H
+
+#include <asm/page.h>
+#include <asm/types.h>
+#include <asm/cpufeature.h>
+#include <asm/desc.h>
+#include <xeno/config.h>
+#include <hypervisor-ifs/hypervisor-if.h>
+
+struct task_struct;
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() \
+  ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ *  Members of this structure are referenced in head.S, so think twice
+ *  before touching them. [mj]
+ */
+
+struct cpuinfo_x86 {
+    __u8       x86;            /* CPU family */
+    __u8       x86_vendor;     /* CPU vendor */
+    __u8       x86_model;
+    __u8       x86_mask;
+    int        cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
+    __u32      x86_capability[NCAPINTS];
+    char    x86_vendor_id[16];
+    unsigned long *pgd_quick;
+    unsigned long *pmd_quick;
+    unsigned long *pte_quick;
+    unsigned long pgtable_cache_sz;
+} __attribute__((__aligned__(SMP_CACHE_BYTES)));
+
+#define X86_VENDOR_INTEL 0
+#define X86_VENDOR_CYRIX 1
+#define X86_VENDOR_AMD 2
+#define X86_VENDOR_UMC 3
+#define X86_VENDOR_NEXGEN 4
+#define X86_VENDOR_CENTAUR 5
+#define X86_VENDOR_RISE 6
+#define X86_VENDOR_TRANSMETA 7
+#define X86_VENDOR_UNKNOWN 0xff
+
+/*
+ * capabilities of CPUs
+ */
+
+extern struct cpuinfo_x86 boot_cpu_data;
+extern struct tss_struct init_tss[NR_CPUS];
+
+#ifdef CONFIG_SMP
+extern struct cpuinfo_x86 cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#else
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+#endif
+
+#define cpu_has_pge    (test_bit(X86_FEATURE_PGE,  boot_cpu_data.x86_capability))
+#define cpu_has_pse    (test_bit(X86_FEATURE_PSE,  boot_cpu_data.x86_capability))
+#define cpu_has_pae    (test_bit(X86_FEATURE_PAE,  boot_cpu_data.x86_capability))
+#define cpu_has_tsc    (test_bit(X86_FEATURE_TSC,  boot_cpu_data.x86_capability))
+#define cpu_has_de     (test_bit(X86_FEATURE_DE,   boot_cpu_data.x86_capability))
+#define cpu_has_vme    (test_bit(X86_FEATURE_VME,  boot_cpu_data.x86_capability))
+#define cpu_has_fxsr   (test_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability))
+#define cpu_has_xmm    (test_bit(X86_FEATURE_XMM,  boot_cpu_data.x86_capability))
+#define cpu_has_fpu    (test_bit(X86_FEATURE_FPU,  boot_cpu_data.x86_capability))
+#define cpu_has_apic   (test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
+
+extern void identify_cpu(struct cpuinfo_x86 *);
+extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void dodgy_tsc(void);
+
+/*
+ * EFLAGS bits
+ */
+#define X86_EFLAGS_CF  0x00000001 /* Carry Flag */
+#define X86_EFLAGS_PF  0x00000004 /* Parity Flag */
+#define X86_EFLAGS_AF  0x00000010 /* Auxillary carry Flag */
+#define X86_EFLAGS_ZF  0x00000040 /* Zero Flag */
+#define X86_EFLAGS_SF  0x00000080 /* Sign Flag */
+#define X86_EFLAGS_TF  0x00000100 /* Trap Flag */
+#define X86_EFLAGS_IF  0x00000200 /* Interrupt Flag */
+#define X86_EFLAGS_DF  0x00000400 /* Direction Flag */
+#define X86_EFLAGS_OF  0x00000800 /* Overflow Flag */
+#define X86_EFLAGS_IOPL        0x00003000 /* IOPL mask */
+#define X86_EFLAGS_NT  0x00004000 /* Nested Task */
+#define X86_EFLAGS_RF  0x00010000 /* Resume Flag */
+#define X86_EFLAGS_VM  0x00020000 /* Virtual Mode */
+#define X86_EFLAGS_AC  0x00040000 /* Alignment Check */
+#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
+#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
+#define X86_EFLAGS_ID  0x00200000 /* CPUID detection flag */
+
+/*
+ * Generic CPUID function
+ */
+static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
+{
+    __asm__("cpuid"
+            : "=a" (*eax),
+            "=b" (*ebx),
+            "=c" (*ecx),
+            "=d" (*edx)
+            : "0" (op));
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+    unsigned int eax;
+
+    __asm__("cpuid"
+            : "=a" (eax)
+            : "0" (op)
+            : "bx", "cx", "dx");
+    return eax;
+}
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+    unsigned int eax, ebx;
+
+    __asm__("cpuid"
+            : "=a" (eax), "=b" (ebx)
+            : "0" (op)
+            : "cx", "dx" );
+    return ebx;
+}
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+    unsigned int eax, ecx;
+
+    __asm__("cpuid"
+            : "=a" (eax), "=c" (ecx)
+            : "0" (op)
+            : "bx", "dx" );
+    return ecx;
+}
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+    unsigned int eax, edx;
+
+    __asm__("cpuid"
+            : "=a" (eax), "=d" (edx)
+            : "0" (op)
+            : "bx", "cx");
+    return edx;
+}
+
+
+/*
+ * Intel CPU flags in CR0
+ */
+#define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
+#define X86_CR0_MP              0x00000002 /* Monitor Coprocessor      (RW) */
+#define X86_CR0_EM              0x00000004 /* Require FPU Emulation    (RO) */
+#define X86_CR0_TS              0x00000008 /* Task Switched            (RW) */
+#define X86_CR0_NE              0x00000020 /* Numeric Error Reporting  (RW) */
+#define X86_CR0_WP              0x00010000 /* Supervisor Write Protect (RW) */
+#define X86_CR0_AM              0x00040000 /* Alignment Checking       (RW) */
+#define X86_CR0_NW              0x20000000 /* Not Write-Through        (RW) */
+#define X86_CR0_CD              0x40000000 /* Cache Disable            (RW) */
+#define X86_CR0_PG              0x80000000 /* Paging                   (RW) */
+
+#define read_cr0() ({ \
+       unsigned int __dummy; \
+       __asm__( \
+               "movl %%cr0,%0\n\t" \
+               :"=r" (__dummy)); \
+       __dummy; \
+})
+
+#define write_cr0(x) \
+       __asm__("movl %0,%%cr0": :"r" (x));
+
+
+
+/*
+ * Intel CPU features in CR4
+ */
+#define X86_CR4_VME            0x0001  /* enable vm86 extensions */
+#define X86_CR4_PVI            0x0002  /* virtual interrupts flag enable */
+#define X86_CR4_TSD            0x0004  /* disable time stamp at ipl 3 */
+#define X86_CR4_DE             0x0008  /* enable debugging extensions */
+#define X86_CR4_PSE            0x0010  /* enable page size extensions */
+#define X86_CR4_PAE            0x0020  /* enable physical address extensions */
+#define X86_CR4_MCE            0x0040  /* Machine check enable */
+#define X86_CR4_PGE            0x0080  /* enable global pages */
+#define X86_CR4_PCE            0x0100  /* enable performance counters at ipl 3 */
+#define X86_CR4_OSFXSR         0x0200  /* enable fast FPU save and restore */
+#define X86_CR4_OSXMMEXCPT     0x0400  /* enable unmasked SSE exceptions */
+
+/*
+ * Save the cr4 feature set we're using (ie
+ * Pentium 4MB enable and PPro Global page
+ * enable), so that any CPU's that boot up
+ * after us can get the correct flags.
+ */
+extern unsigned long mmu_cr4_features;
+
+static inline void set_in_cr4 (unsigned long mask)
+{
+    mmu_cr4_features |= mask;
+    __asm__("movl %%cr4,%%eax\n\t"
+            "orl %0,%%eax\n\t"
+            "movl %%eax,%%cr4\n"
+            : : "irg" (mask)
+            :"ax");
+}
+
+static inline void clear_in_cr4 (unsigned long mask)
+{
+    mmu_cr4_features &= ~mask;
+    __asm__("movl %%cr4,%%eax\n\t"
+            "andl %0,%%eax\n\t"
+            "movl %%eax,%%cr4\n"
+            : : "irg" (~mask)
+            :"ax");
+}
+
+/*
+ *      Cyrix CPU configuration register indexes
+ */
+#define CX86_CCR0 0xc0
+#define CX86_CCR1 0xc1
+#define CX86_CCR2 0xc2
+#define CX86_CCR3 0xc3
+#define CX86_CCR4 0xe8
+#define CX86_CCR5 0xe9
+#define CX86_CCR6 0xea
+#define CX86_CCR7 0xeb
+#define CX86_DIR0 0xfe
+#define CX86_DIR1 0xff
+#define CX86_ARR_BASE 0xc4
+#define CX86_RCR_BASE 0xdc
+
+/*
+ *      Cyrix CPU indexed register access macros
+ */
+
+#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
+
+#define setCx86(reg, data) do { \
+       outb((reg), 0x22); \
+       outb((data), 0x23); \
+} while (0)
+
+#define EISA_bus (0)
+#define MCA_bus  (0)
+
+/* from system description table in BIOS.  Mostly for MCA use, but
+others may find it useful. */
+extern unsigned int machine_id;
+extern unsigned int machine_submodel_id;
+extern unsigned int BIOS_revision;
+extern unsigned int mca_pentium_flag;
+
+/*
+ * User space process size: 3GB (default).
+ */
+#define TASK_SIZE      (PAGE_OFFSET)
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
+/*
+ * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
+ */
+#define IO_BITMAP_SIZE 32
+#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
+#define INVALID_IO_BITMAP_OFFSET 0x8000
+
+struct i387_fsave_struct {
+    long       cwd;
+    long       swd;
+    long       twd;
+    long       fip;
+    long       fcs;
+    long       foo;
+    long       fos;
+    long       st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
+};
+
+struct i387_fxsave_struct {
+    unsigned short     cwd;
+    unsigned short     swd;
+    unsigned short     twd;
+    unsigned short     fop;
+    long       fip;
+    long       fcs;
+    long       foo;
+    long       fos;
+    long       mxcsr;
+    long       reserved;
+    long       st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
+    long       xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
+    long       padding[56];
+} __attribute__ ((aligned (16)));
+
+union i387_union {
+    struct i387_fsave_struct   fsave;
+    struct i387_fxsave_struct  fxsave;
+};
+
+typedef struct {
+    unsigned long seg;
+} mm_segment_t;
+
+struct tss_struct {
+    unsigned short     back_link,__blh;
+    unsigned long      esp0;
+    unsigned short     ss0,__ss0h;
+    unsigned long      esp1;
+    unsigned short     ss1,__ss1h;
+    unsigned long      esp2;
+    unsigned short     ss2,__ss2h;
+    unsigned long      __cr3;
+    unsigned long      eip;
+    unsigned long      eflags;
+    unsigned long      eax,ecx,edx,ebx;
+    unsigned long      esp;
+    unsigned long      ebp;
+    unsigned long      esi;
+    unsigned long      edi;
+    unsigned short     es, __esh;
+    unsigned short     cs, __csh;
+    unsigned short     ss, __ssh;
+    unsigned short     ds, __dsh;
+    unsigned short     fs, __fsh;
+    unsigned short     gs, __gsh;
+    unsigned short     ldt, __ldth;
+    unsigned short     trace, bitmap;
+    unsigned long      io_bitmap[IO_BITMAP_SIZE+1];
+    /*
+     * pads the TSS to be cacheline-aligned (size is 0x100)
+     */
+    unsigned long __cacheline_filler[5];
+};
+
+struct thread_struct {
+    unsigned long esp1, ss1;
+/* Hardware debugging registers */
+    unsigned long      debugreg[8];  /* %%db0-7 debug registers */
+/* floating point info */
+    union i387_union   i387;
+/* Trap info. */
+    int                 fast_trap_idx;
+    struct desc_struct  fast_trap_desc;
+    trap_info_t         traps[256];
+};
+
+#define IDT_ENTRIES 256
+extern struct desc_struct idt_table[];
+extern struct desc_struct *idt_tables[];
+
+#define SET_DEFAULT_FAST_TRAP(_p) \
+    (_p)->fast_trap_idx = 0x20;   \
+    (_p)->fast_trap_desc.a = 0;   \
+    (_p)->fast_trap_desc.b = 0;
+
+#define CLEAR_FAST_TRAP(_p) \
+    (memset(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
+     0, 8))
+
+#define SET_FAST_TRAP(_p)   \
+    (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
+     &((_p)->fast_trap_desc), 8))
+
+long set_fast_trap(struct task_struct *p, int idx);
+
+#define INIT_THREAD  {                                         \
+       0, 0,                                                   \
+       { [0 ... 7] = 0 },      /* debugging registers */       \
+       { { 0, }, },            /* 387 state */                 \
+       0x20, { 0, 0 },         /* DEFAULT_FAST_TRAP */         \
+       { {0} }                 /* io permissions */            \
+}
+
+#define INIT_TSS  {                                            \
+       0,0, /* back_link, __blh */                             \
+       0, /* esp0 */                                           \
+       0, 0, /* ss0 */                                         \
+       0,0,0,0,0,0, /* stack1, stack2 */                       \
+       0, /* cr3 */                                            \
+       0,0, /* eip,eflags */                                   \
+       0,0,0,0, /* eax,ecx,edx,ebx */                          \
+       0,0,0,0, /* esp,ebp,esi,edi */                          \
+       0,0,0,0,0,0, /* es,cs,ss */                             \
+       0,0,0,0,0,0, /* ds,fs,gs */                             \
+       0,0, /* ldt */                                          \
+       0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */         \
+       {~0, } /* ioperm */                                     \
+}
+
+struct mm_struct {
+    /*
+     * Every domain has a L1 pagetable of its own. Per-domain mappings
+     * are put in this table (eg. the current GDT is mapped here).
+     */
+    l1_pgentry_t *perdomain_pt;
+    pagetable_t  pagetable;
+    /* Current LDT details. */
+    unsigned long ldt_base, ldt_ents, shadow_ldt_mapcnt;
+    /* Next entry is passed to LGDT on domain switch. */
+    char gdt[6];
+};
+
+#define IDLE0_MM                                                    \
+{                                                                   \
+    perdomain_pt: 0,                                                \
+    pagetable:   mk_pagetable(__pa(idle_pg_table))                  \
+}
+
+/* Convenient accessor for mm.gdt. */
+#define SET_GDT_ENTRIES(_p, _e) ((*(u16 *)((_p)->mm.gdt + 0)) = (_e))
+#define SET_GDT_ADDRESS(_p, _a) ((*(u32 *)((_p)->mm.gdt + 2)) = (_a))
+#define GET_GDT_ENTRIES(_p)     ((*(u16 *)((_p)->mm.gdt + 0)))
+#define GET_GDT_ADDRESS(_p)     ((*(u32 *)((_p)->mm.gdt + 2)))
+
+long set_gdt(struct task_struct *p, 
+             unsigned long *frames, 
+             unsigned int entries);
+
+long set_debugreg(struct task_struct *p, int reg, unsigned long value);
+
+struct microcode {
+    unsigned int hdrver;
+    unsigned int rev;
+    unsigned int date;
+    unsigned int sig;
+    unsigned int cksum;
+    unsigned int ldrver;
+    unsigned int pf;
+    unsigned int reserved[5];
+    unsigned int bits[500];
+};
+
+/* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */
+#define MICROCODE_IOCFREE      _IO('6',0)
+
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+static inline void rep_nop(void)
+{
+    __asm__ __volatile__("rep;nop");
+}
+
+#define cpu_relax()    rep_nop()
+
+/* Prefetch instructions for Pentium III and AMD Athlon */
+#ifdef         CONFIG_MPENTIUMIII
+
+#define ARCH_HAS_PREFETCH
+extern inline void prefetch(const void *x)
+{
+    __asm__ __volatile__ ("prefetchnta (%0)" : : "r"(x));
+}
+
+#elif CONFIG_X86_USE_3DNOW
+
+#define ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCHW
+#define ARCH_HAS_SPINLOCK_PREFETCH
+
+extern inline void prefetch(const void *x)
+{
+    __asm__ __volatile__ ("prefetch (%0)" : : "r"(x));
+}
+
+extern inline void prefetchw(const void *x)
+{
+    __asm__ __volatile__ ("prefetchw (%0)" : : "r"(x));
+}
+#define spin_lock_prefetch(x)  prefetchw(x)
+
+#endif
+
+#endif /* __ASM_I386_PROCESSOR_H */
diff --git a/xen/include/asm-x86_64/ptrace.h b/xen/include/asm-x86_64/ptrace.h
new file mode 100644 (file)
index 0000000..26269af
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _I386_PTRACE_H
+#define _I386_PTRACE_H
+
+struct pt_regs {
+       long ebx;
+       long ecx;
+       long edx;
+       long esi;
+       long edi;
+       long ebp;
+       long eax;
+       int  xds;
+       int  xes;
+       int  xfs;
+       int  xgs;
+       long orig_eax;
+       long eip;
+       int  xcs;
+       long eflags;
+       long esp;
+       int  xss;
+};
+
+enum EFLAGS {
+        EF_CF   = 0x00000001,
+        EF_PF   = 0x00000004,
+        EF_AF   = 0x00000010,
+        EF_ZF   = 0x00000040,
+        EF_SF   = 0x00000080,
+        EF_TF   = 0x00000100,
+        EF_IE   = 0x00000200,
+        EF_DF   = 0x00000400,
+        EF_OF   = 0x00000800,
+        EF_IOPL = 0x00003000,
+        EF_IOPL_RING0 = 0x00000000,
+        EF_IOPL_RING1 = 0x00001000,
+        EF_IOPL_RING2 = 0x00002000,
+        EF_NT   = 0x00004000,   /* nested task */
+        EF_RF   = 0x00010000,   /* resume */
+        EF_VM   = 0x00020000,   /* virtual mode */
+        EF_AC   = 0x00040000,   /* alignment */
+        EF_VIF  = 0x00080000,   /* virtual interrupt */
+        EF_VIP  = 0x00100000,   /* virtual interrupt pending */
+        EF_ID   = 0x00200000,   /* id */
+};
+
+#ifdef __KERNEL__
+#define user_mode(regs) ((3 & (regs)->xcs))
+#endif
+
+#endif
diff --git a/xen/include/asm-x86_64/rwlock.h b/xen/include/asm-x86_64/rwlock.h
new file mode 100644 (file)
index 0000000..9475419
--- /dev/null
@@ -0,0 +1,83 @@
+/* include/asm-i386/rwlock.h
+ *
+ *     Helpers used by both rw spinlocks and rw semaphores.
+ *
+ *     Based in part on code from semaphore.h and
+ *     spinlock.h Copyright 1996 Linus Torvalds.
+ *
+ *     Copyright 1999 Red Hat, Inc.
+ *
+ *     Written by Benjamin LaHaise.
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_I386_RWLOCK_H
+#define _ASM_I386_RWLOCK_H
+
+#define RW_LOCK_BIAS            0x01000000
+#define RW_LOCK_BIAS_STR       "0x01000000"
+
+#define __build_read_lock_ptr(rw, helper)   \
+       asm volatile(LOCK "subl $1,(%0)\n\t" \
+                    "js 2f\n" \
+                    "1:\n" \
+                    ".section .text.lock,\"ax\"\n" \
+                    "2:\tcall " helper "\n\t" \
+                    "jmp 1b\n" \
+                    ".previous" \
+                    ::"a" (rw) : "memory")
+
+#define __build_read_lock_const(rw, helper)   \
+       asm volatile(LOCK "subl $1,%0\n\t" \
+                    "js 2f\n" \
+                    "1:\n" \
+                    ".section .text.lock,\"ax\"\n" \
+                    "2:\tpushl %%eax\n\t" \
+                    "leal %0,%%eax\n\t" \
+                    "call " helper "\n\t" \
+                    "popl %%eax\n\t" \
+                    "jmp 1b\n" \
+                    ".previous" \
+                    :"=m" (*(volatile int *)rw) : : "memory")
+
+#define __build_read_lock(rw, helper)  do { \
+                                               if (__builtin_constant_p(rw)) \
+                                                       __build_read_lock_const(rw, helper); \
+                                               else \
+                                                       __build_read_lock_ptr(rw, helper); \
+                                       } while (0)
+
+#define __build_write_lock_ptr(rw, helper) \
+       asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+                    "jnz 2f\n" \
+                    "1:\n" \
+                    ".section .text.lock,\"ax\"\n" \
+                    "2:\tcall " helper "\n\t" \
+                    "jmp 1b\n" \
+                    ".previous" \
+                    ::"a" (rw) : "memory")
+
+#define __build_write_lock_const(rw, helper) \
+       asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+                    "jnz 2f\n" \
+                    "1:\n" \
+                    ".section .text.lock,\"ax\"\n" \
+                    "2:\tpushl %%eax\n\t" \
+                    "leal %0,%%eax\n\t" \
+                    "call " helper "\n\t" \
+                    "popl %%eax\n\t" \
+                    "jmp 1b\n" \
+                    ".previous" \
+                    :"=m" (*(volatile int *)rw) : : "memory")
+
+#define __build_write_lock(rw, helper) do { \
+                                               if (__builtin_constant_p(rw)) \
+                                                       __build_write_lock_const(rw, helper); \
+                                               else \
+                                                       __build_write_lock_ptr(rw, helper); \
+                                       } while (0)
+
+#endif
diff --git a/xen/include/asm-x86_64/scatterlist.h b/xen/include/asm-x86_64/scatterlist.h
new file mode 100644 (file)
index 0000000..9d85841
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _I386_SCATTERLIST_H
+#define _I386_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to, NULL for
+                        * highmem page */
+    struct pfn_info * page; /* Location for highmem page, if any */
+    unsigned int offset;/* for highmem, page offset */
+
+    dma_addr_t dma_address;
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_I386_SCATTERLIST_H) */
diff --git a/xen/include/asm-x86_64/smp.h b/xen/include/asm-x86_64/smp.h
new file mode 100644 (file)
index 0000000..58a0a24
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#include <xeno/config.h>
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_SMP
+#define TARGET_CPUS cpu_online_map
+#else
+#define TARGET_CPUS 0x01
+#endif
+
+#ifdef CONFIG_SMP
+/*
+ * Private routines/data
+ */
+extern void smp_alloc_memory(void);
+extern unsigned long phys_cpu_present_map;
+extern unsigned long cpu_online_map;
+extern volatile unsigned long smp_invalidate_needed;
+extern int pic_mode;
+extern void smp_flush_tlb(void);
+extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
+extern void smp_invalidate_rcv(void);          /* Process an NMI */
+extern void (*mtrr_hook) (void);
+extern void zap_low_mappings (void);
+
+/*
+ * On x86 all CPUs are mapped 1:1 to the APIC space.
+ * This simplifies scheduling and IPI sending and
+ * compresses data structures.
+ */
+static inline int cpu_logical_map(int cpu)
+{
+       return cpu;
+}
+static inline int cpu_number_map(int cpu)
+{
+       return cpu;
+}
+
+/*
+ * Some lowlevel functions might want to know about
+ * the real APIC ID <-> CPU # mapping.
+ */
+#define MAX_APICID 256
+extern volatile int cpu_to_physical_apicid[NR_CPUS];
+extern volatile int physical_apicid_to_cpu[MAX_APICID];
+extern volatile int cpu_to_logical_apicid[NR_CPUS];
+extern volatile int logical_apicid_to_cpu[MAX_APICID];
+
+/*
+ * General functions that each host system must provide.
+ */
+extern void smp_store_cpu_info(int id);                /* Store per CPU info (like the initial udelay numbers */
+
+/*
+ * This function is needed by all SMP systems. It must _always_ be valid
+ * from the initial startup. We map APIC_BASE very early in page_setup(),
+ * so this is correct in the x86 case.
+ */
+
+#define smp_processor_id() (current->processor)
+
+#include <asm/fixmap.h>
+#include <asm/apic.h>
+
+static __inline int hard_smp_processor_id(void)
+{
+       /* we don't want to mark this access volatile - bad code generation */
+       return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID));
+}
+
+static __inline int logical_smp_processor_id(void)
+{
+       /* we don't want to mark this access volatile - bad code generation */
+       return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
+}
+
+#endif
+#endif
diff --git a/xen/include/asm-x86_64/smpboot.h b/xen/include/asm-x86_64/smpboot.h
new file mode 100644 (file)
index 0000000..4017902
--- /dev/null
@@ -0,0 +1,130 @@
+#ifndef __ASM_SMPBOOT_H
+#define __ASM_SMPBOOT_H
+
+/*emum for clustered_apic_mode values*/
+enum{
+       CLUSTERED_APIC_NONE = 0,
+       CLUSTERED_APIC_XAPIC,
+       CLUSTERED_APIC_NUMAQ
+};
+
+#ifdef CONFIG_X86_CLUSTERED_APIC
+extern unsigned int apic_broadcast_id;
+extern unsigned char clustered_apic_mode;
+extern unsigned char esr_disable;
+extern unsigned char int_delivery_mode;
+extern unsigned int int_dest_addr_mode;
+extern int cyclone_setup(char*);
+
+static inline void detect_clustered_apic(char* oem, char* prod)
+{
+       /*
+        * Can't recognize Summit xAPICs at present, so use the OEM ID.
+        */
+       if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){
+               clustered_apic_mode = CLUSTERED_APIC_XAPIC;
+               apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
+               int_dest_addr_mode = APIC_DEST_PHYSICAL;
+               int_delivery_mode = dest_Fixed;
+               esr_disable = 1;
+               /*Start cyclone clock*/
+               cyclone_setup(0);
+       }
+       else if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "RUTHLESS SMP", 9)){
+               clustered_apic_mode = CLUSTERED_APIC_XAPIC;
+               apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
+               int_dest_addr_mode = APIC_DEST_PHYSICAL;
+               int_delivery_mode = dest_Fixed;
+               esr_disable = 1;
+               /*Start cyclone clock*/
+               cyclone_setup(0);
+       }
+       else if (!strncmp(oem, "IBM NUMA", 8)){
+               clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
+               apic_broadcast_id = APIC_BROADCAST_ID_APIC;
+               int_dest_addr_mode = APIC_DEST_LOGICAL;
+               int_delivery_mode = dest_LowestPrio;
+               esr_disable = 1;
+       }
+}
+#define        INT_DEST_ADDR_MODE (int_dest_addr_mode)
+#define        INT_DELIVERY_MODE (int_delivery_mode)
+#else /* CONFIG_X86_CLUSTERED_APIC */
+#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
+#define clustered_apic_mode (CLUSTERED_APIC_NONE)
+#define esr_disable (0)
+#define detect_clustered_apic(x,y)
+#define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL) /* logical delivery */
+#define INT_DELIVERY_MODE (dest_LowestPrio)
+#endif /* CONFIG_X86_CLUSTERED_APIC */
+#define BAD_APICID 0xFFu
+
+#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
+#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)
+
+#define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid)
+
+extern unsigned char raw_phys_apicid[NR_CPUS];
+
+/*
+ * How to map from the cpu_present_map
+ */
+static inline int cpu_present_to_apicid(int mps_cpu)
+{
+       if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+               return raw_phys_apicid[mps_cpu];
+       if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+               return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
+       return mps_cpu;
+}
+
+static inline unsigned long apicid_to_phys_cpu_present(int apicid)
+{
+       if(clustered_apic_mode)
+               return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3));
+       return 1UL << apicid;
+}
+
+#define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) )
+
+/*
+ * Mappings between logical cpu number and logical / physical apicid
+ * The first four macros are trivial, but it keeps the abstraction consistent
+ */
+extern volatile int logical_apicid_2_cpu[];
+extern volatile int cpu_2_logical_apicid[];
+extern volatile int physical_apicid_2_cpu[];
+extern volatile int cpu_2_physical_apicid[];
+
+#define logical_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
+#define cpu_to_logical_apicid(cpu) cpu_2_logical_apicid[cpu]
+#define physical_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
+#define cpu_to_physical_apicid(cpu) cpu_2_physical_apicid[cpu]
+#ifdef CONFIG_MULTIQUAD                        /* use logical IDs to bootstrap */
+#define boot_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
+#define cpu_to_boot_apicid(cpu) cpu_2_logical_apicid[cpu]
+#else /* !CONFIG_MULTIQUAD */          /* use physical IDs to bootstrap */
+#define boot_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
+#define cpu_to_boot_apicid(cpu) cpu_2_physical_apicid[cpu]
+#endif /* CONFIG_MULTIQUAD */
+
+#ifdef CONFIG_X86_CLUSTERED_APIC
+static inline int target_cpus(void)
+{
+       static int cpu;
+       switch(clustered_apic_mode){
+               case CLUSTERED_APIC_NUMAQ:
+                       /* Broadcast intrs to local quad only. */
+                       return APIC_BROADCAST_ID_APIC;
+               case CLUSTERED_APIC_XAPIC:
+                       /*round robin the interrupts*/
+                       cpu = (cpu+1)%smp_num_cpus;
+                       return cpu_to_physical_apicid(cpu);
+               default:
+       }
+       return cpu_online_map;
+}
+#else
+#define target_cpus() (0xFF)
+#endif
+#endif
diff --git a/xen/include/asm-x86_64/softirq.h b/xen/include/asm-x86_64/softirq.h
new file mode 100644 (file)
index 0000000..292baac
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __ASM_SOFTIRQ_H
+#define __ASM_SOFTIRQ_H
+
+#include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+#define cpu_bh_enable(cpu) \
+               do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+               do { local_bh_count(cpu)++; barrier(); } while (0)
+
+#define local_bh_disable()  cpu_bh_disable(smp_processor_id())
+#define local_bh_enable()   cpu_bh_enable(smp_processor_id())
+
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
+
+#endif /* __ASM_SOFTIRQ_H */
diff --git a/xen/include/asm-x86_64/spinlock.h b/xen/include/asm-x86_64/spinlock.h
new file mode 100644 (file)
index 0000000..9a4fc85
--- /dev/null
@@ -0,0 +1,205 @@
+#ifndef __ASM_SPINLOCK_H
+#define __ASM_SPINLOCK_H
+
+#include <xeno/config.h>
+#include <xeno/lib.h>
+#include <asm/atomic.h>
+#include <asm/rwlock.h>
+
+#if 0
+#define SPINLOCK_DEBUG 1
+#else
+#define SPINLOCK_DEBUG 0
+#endif
+
+/*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+ */
+
+typedef struct {
+       volatile unsigned int lock;
+#if SPINLOCK_DEBUG
+       unsigned magic;
+#endif
+} spinlock_t;
+
+#define SPINLOCK_MAGIC 0xdead4ead
+
+#if SPINLOCK_DEBUG
+#define SPINLOCK_MAGIC_INIT    , SPINLOCK_MAGIC
+#else
+#define SPINLOCK_MAGIC_INIT    /* */
+#endif
+
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
+
+#define spin_lock_init(x)      do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
+
+/*
+ * Simple spin lock operations.  There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions. They have a cost.
+ */
+
+#define spin_is_locked(x)      (*(volatile char *)(&(x)->lock) <= 0)
+#define spin_unlock_wait(x)    do { barrier(); } while(spin_is_locked(x))
+
+#define spin_lock_string \
+       "\n1:\t" \
+       "lock ; decb %0\n\t" \
+       "js 2f\n" \
+       ".section .text.lock,\"ax\"\n" \
+       "2:\t" \
+       "cmpb $0,%0\n\t" \
+       "rep;nop\n\t" \
+       "jle 2b\n\t" \
+       "jmp 1b\n" \
+       ".previous"
+
+/*
+ * This works. Despite all the confusion.
+ * (except on PPro SMP or if we are using OOSTORE)
+ * (PPro errata 66, 92)
+ */
+#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)
+
+#define spin_unlock_string \
+       "movb $1,%0" \
+               :"=m" (lock->lock) : : "memory"
+
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+#if SPINLOCK_DEBUG
+       if (lock->magic != SPINLOCK_MAGIC)
+               BUG();
+       if (!spin_is_locked(lock))
+               BUG();
+#endif
+       __asm__ __volatile__(
+               spin_unlock_string
+       );
+}
+
+#else
+
+#define spin_unlock_string \
+       "xchgb %b0, %1" \
+               :"=q" (oldval), "=m" (lock->lock) \
+               :"0" (oldval) : "memory"
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+       char oldval = 1;
+#if SPINLOCK_DEBUG
+       if (lock->magic != SPINLOCK_MAGIC)
+               BUG();
+       if (!spin_is_locked(lock))
+               BUG();
+#endif
+       __asm__ __volatile__(
+               spin_unlock_string
+       );
+}
+
+#endif
+
+static inline int spin_trylock(spinlock_t *lock)
+{
+       char oldval;
+       __asm__ __volatile__(
+               "xchgb %b0,%1"
+               :"=q" (oldval), "=m" (lock->lock)
+               :"0" (0) : "memory");
+       return oldval > 0;
+}
+
+static inline void spin_lock(spinlock_t *lock)
+{
+#if SPINLOCK_DEBUG
+       __label__ here;
+here:
+       if (lock->magic != SPINLOCK_MAGIC) {
+printk("eip: %p\n", &&here);
+               BUG();
+       }
+#endif
+       __asm__ __volatile__(
+               spin_lock_string
+               :"=m" (lock->lock) : : "memory");
+}
+
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+typedef struct {
+       volatile unsigned int lock;
+#if SPINLOCK_DEBUG
+       unsigned magic;
+#endif
+} rwlock_t;
+
+#define RWLOCK_MAGIC   0xdeaf1eed
+
+#if SPINLOCK_DEBUG
+#define RWLOCK_MAGIC_INIT      , RWLOCK_MAGIC
+#else
+#define RWLOCK_MAGIC_INIT      /* */
+#endif
+
+#define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
+
+#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+
+/*
+ * On x86, we implement read-write locks as a 32-bit counter
+ * with the high bit (sign) being the "contended" bit.
+ *
+ * The inline assembly is non-obvious. Think about it.
+ *
+ * Changed to use the same technique as rw semaphores.  See
+ * semaphore.h for details.  -ben
+ */
+/* the spinlock helpers are in arch/i386/kernel/semaphore.c */
+
+static inline void read_lock(rwlock_t *rw)
+{
+#if SPINLOCK_DEBUG
+       if (rw->magic != RWLOCK_MAGIC)
+               BUG();
+#endif
+       __build_read_lock(rw, "__read_lock_failed");
+}
+
+static inline void write_lock(rwlock_t *rw)
+{
+#if SPINLOCK_DEBUG
+       if (rw->magic != RWLOCK_MAGIC)
+               BUG();
+#endif
+       __build_write_lock(rw, "__write_lock_failed");
+}
+
+#define read_unlock(rw)                asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
+#define write_unlock(rw)       asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
+
+static inline int write_trylock(rwlock_t *lock)
+{
+       atomic_t *count = (atomic_t *)lock;
+       if (atomic_sub_and_test(RW_LOCK_BIAS, count))
+               return 1;
+       atomic_add(RW_LOCK_BIAS, count);
+       return 0;
+}
+
+#endif /* __ASM_SPINLOCK_H */
diff --git a/xen/include/asm-x86_64/string.h b/xen/include/asm-x86_64/string.h
new file mode 100644 (file)
index 0000000..385da59
--- /dev/null
@@ -0,0 +1,500 @@
+#ifndef _I386_STRING_H_
+#define _I386_STRING_H_
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+/*
+ * On a 486 or Pentium, we are better off not using the
+ * byte string operations. But on a 386 or a PPro the
+ * byte string ops are faster than doing it by hand
+ * (MUCH faster on a Pentium).
+ *
+ * Also, the byte strings actually work correctly. Forget
+ * the i486 routines for now as they may be broken..
+ */
+#if FIXED_486_STRING && defined(CONFIG_X86_USE_STRING_486)
+#include <asm/string-486.h>
+#else
+
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ *             NO Copyright (C) 1991, 1992 Linus Torvalds,
+ *             consider these trivial functions to be PD.
+ */
+
+
+#define __HAVE_ARCH_STRCPY
+static inline char * strcpy(char * dest,const char *src)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+       "1:\tlodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b"
+       : "=&S" (d0), "=&D" (d1), "=&a" (d2)
+       :"0" (src),"1" (dest) : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+static inline char * strncpy(char * dest,const char *src,size_t count)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+       "1:\tdecl %2\n\t"
+       "js 2f\n\t"
+       "lodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n\t"
+       "rep\n\t"
+       "stosb\n"
+       "2:"
+       : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
+       :"0" (src),"1" (dest),"2" (count) : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRCAT
+static inline char * strcat(char * dest,const char * src)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "decl %1\n"
+       "1:\tlodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b"
+       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+       : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRNCAT
+static inline char * strncat(char * dest,const char * src,size_t count)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "decl %1\n\t"
+       "movl %8,%3\n"
+       "1:\tdecl %3\n\t"
+       "js 2f\n\t"
+       "lodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n"
+       "2:\txorl %2,%2\n\t"
+       "stosb"
+       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+       : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+       : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char * cs,const char * ct)
+{
+int d0, d1;
+register int __res;
+__asm__ __volatile__(
+       "1:\tlodsb\n\t"
+       "scasb\n\t"
+       "jne 2f\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n\t"
+       "xorl %%eax,%%eax\n\t"
+       "jmp 3f\n"
+       "2:\tsbbl %%eax,%%eax\n\t"
+       "orb $1,%%al\n"
+       "3:"
+       :"=a" (__res), "=&S" (d0), "=&D" (d1)
+                    :"1" (cs),"2" (ct));
+return __res;
+}
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+register int __res;
+int d0, d1, d2;
+__asm__ __volatile__(
+       "1:\tdecl %3\n\t"
+       "js 2f\n\t"
+       "lodsb\n\t"
+       "scasb\n\t"
+       "jne 3f\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n"
+       "2:\txorl %%eax,%%eax\n\t"
+       "jmp 4f\n"
+       "3:\tsbbl %%eax,%%eax\n\t"
+       "orb $1,%%al\n"
+       "4:"
+                    :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+                    :"1" (cs),"2" (ct),"3" (count));
+return __res;
+}
+
+#define __HAVE_ARCH_STRCHR
+static inline char * strchr(const char * s, int c)
+{
+int d0;
+register char * __res;
+__asm__ __volatile__(
+       "movb %%al,%%ah\n"
+       "1:\tlodsb\n\t"
+       "cmpb %%ah,%%al\n\t"
+       "je 2f\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n\t"
+       "movl $1,%1\n"
+       "2:\tmovl %1,%0\n\t"
+       "decl %0"
+       :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
+return __res;
+}
+
+#define __HAVE_ARCH_STRRCHR
+static inline char * strrchr(const char * s, int c)
+{
+int d0, d1;
+register char * __res;
+__asm__ __volatile__(
+       "movb %%al,%%ah\n"
+       "1:\tlodsb\n\t"
+       "cmpb %%ah,%%al\n\t"
+       "jne 2f\n\t"
+       "leal -1(%%esi),%0\n"
+       "2:\ttestb %%al,%%al\n\t"
+       "jne 1b"
+       :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
+return __res;
+}
+
+#define __HAVE_ARCH_STRLEN
+static inline size_t strlen(const char * s)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "notl %0\n\t"
+       "decl %0"
+       :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
+return __res;
+}
+
+static inline void * __memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+       "rep ; movsl\n\t"
+       "testb $2,%b4\n\t"
+       "je 1f\n\t"
+       "movsw\n"
+       "1:\ttestb $1,%b4\n\t"
+       "je 2f\n\t"
+       "movsb\n"
+       "2:"
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+       :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+       : "memory");
+return (to);
+}
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as the count is constant.
+ */
+static inline void * __constant_memcpy(void * to, const void * from, size_t n)
+{
+       switch (n) {
+               case 0:
+                       return to;
+               case 1:
+                       *(unsigned char *)to = *(const unsigned char *)from;
+                       return to;
+               case 2:
+                       *(unsigned short *)to = *(const unsigned short *)from;
+                       return to;
+               case 3:
+                       *(unsigned short *)to = *(const unsigned short *)from;
+                       *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
+                       return to;
+               case 4:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       return to;
+               case 6: /* for Ethernet addresses */
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
+                       return to;
+               case 8:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       return to;
+               case 12:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+                       return to;
+               case 16:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+                       *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+                       return to;
+               case 20:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+                       *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+                       *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
+                       return to;
+       }
+#define COMMON(x) \
+__asm__ __volatile__( \
+       "rep ; movsl" \
+       x \
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
+       : "0" (n/4),"1" ((long) to),"2" ((long) from) \
+       : "memory");
+{
+       int d0, d1, d2;
+       switch (n % 4) {
+               case 0: COMMON(""); return to;
+               case 1: COMMON("\n\tmovsb"); return to;
+               case 2: COMMON("\n\tmovsw"); return to;
+               default: COMMON("\n\tmovsw\n\tmovsb"); return to;
+       }
+}
+  
+#undef COMMON
+}
+
+#define __HAVE_ARCH_MEMCPY
+
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __memcpy((t),(f),(n)))
+
+
+/*
+ * struct_cpy(x,y), copy structure *x into (matching structure) *y.
+ *
+ * We get link-time errors if the structure sizes do not match.
+ * There is no runtime overhead, it's all optimized away at
+ * compile time.
+ */
+//extern void __struct_cpy_bug (void);
+
+/*
+#define struct_cpy(x,y)                        \
+({                                             \
+       if (sizeof(*(x)) != sizeof(*(y)))       \
+               __struct_cpy_bug;               \
+       memcpy(x, y, sizeof(*(x)));             \
+})
+*/
+
+#define __HAVE_ARCH_MEMMOVE
+static inline void * memmove(void * dest,const void * src, size_t n)
+{
+int d0, d1, d2;
+if (dest<src)
+__asm__ __volatile__(
+       "rep\n\t"
+       "movsb"
+       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+       :"0" (n),"1" (src),"2" (dest)
+       : "memory");
+else
+__asm__ __volatile__(
+       "std\n\t"
+       "rep\n\t"
+       "movsb\n\t"
+       "cld"
+       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+       :"0" (n),
+        "1" (n-1+(const char *)src),
+        "2" (n-1+(char *)dest)
+       :"memory");
+return dest;
+}
+
+#define memcmp __builtin_memcmp
+
+#define __HAVE_ARCH_MEMCHR
+static inline void * memchr(const void * cs,int c,size_t count)
+{
+int d0;
+register void * __res;
+if (!count)
+       return NULL;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "je 1f\n\t"
+       "movl $1,%0\n"
+       "1:\tdecl %0"
+       :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
+return __res;
+}
+
+static inline void * __memset_generic(void * s, char c,size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+       "rep\n\t"
+       "stosb"
+       : "=&c" (d0), "=&D" (d1)
+       :"a" (c),"1" (s),"0" (count)
+       :"memory");
+return s;
+}
+
+/* we might want to write optimized versions of these later */
+#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
+
+/*
+ * memset(x,0,y) is a reasonably common thing to do, so we want to fill
+ * things 32 bits at a time even when we don't know the size of the
+ * area at compile-time..
+ */
+static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+       "rep ; stosl\n\t"
+       "testb $2,%b3\n\t"
+       "je 1f\n\t"
+       "stosw\n"
+       "1:\ttestb $1,%b3\n\t"
+       "je 2f\n\t"
+       "stosb\n"
+       "2:"
+       : "=&c" (d0), "=&D" (d1)
+       :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
+       :"memory");
+return (s);    
+}
+
+/* Added by Gertjan van Wingerde to make minix and sysv module work */
+#define __HAVE_ARCH_STRNLEN
+static inline size_t strnlen(const char * s, size_t count)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+       "movl %2,%0\n\t"
+       "jmp 2f\n"
+       "1:\tcmpb $0,(%0)\n\t"
+       "je 3f\n\t"
+       "incl %0\n"
+       "2:\tdecl %1\n\t"
+       "cmpl $-1,%1\n\t"
+       "jne 1b\n"
+       "3:\tsubl %2,%0"
+       :"=a" (__res), "=&d" (d0)
+       :"c" (s),"1" (count));
+return __res;
+}
+/* end of additional stuff */
+
+//#define __HAVE_ARCH_STRSTR
+
+//extern char *strstr(const char *cs, const char *ct);
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as we by now know that both pattern and count is constant..
+ */
+static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+{
+       switch (count) {
+               case 0:
+                       return s;
+               case 1:
+                       *(unsigned char *)s = pattern;
+                       return s;
+               case 2:
+                       *(unsigned short *)s = pattern;
+                       return s;
+               case 3:
+                       *(unsigned short *)s = pattern;
+                       *(2+(unsigned char *)s) = pattern;
+                       return s;
+               case 4:
+                       *(unsigned long *)s = pattern;
+                       return s;
+       }
+#define COMMON(x) \
+__asm__  __volatile__( \
+       "rep ; stosl" \
+       x \
+       : "=&c" (d0), "=&D" (d1) \
+       : "a" (pattern),"0" (count/4),"1" ((long) s) \
+       : "memory")
+{
+       int d0, d1;
+       switch (count % 4) {
+               case 0: COMMON(""); return s;
+               case 1: COMMON("\n\tstosb"); return s;
+               case 2: COMMON("\n\tstosw"); return s;
+               default: COMMON("\n\tstosw\n\tstosb"); return s;
+       }
+}
+  
+#undef COMMON
+}
+
+#define __constant_c_x_memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_c_and_count_memset((s),(c),(count)) : \
+ __constant_c_memset((s),(c),(count)))
+
+#define __memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_count_memset((s),(c),(count)) : \
+ __memset_generic((s),(c),(count)))
+
+#define __HAVE_ARCH_MEMSET
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? \
+ __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
+ __memset((s),(c),(count)))
+
+/*
+ * find the first occurrence of byte 'c', or 1 past the area if none
+ */
+#define __HAVE_ARCH_MEMSCAN
+static inline void * memscan(void * addr, int c, size_t size)
+{
+       if (!size)
+               return addr;
+       __asm__("repnz; scasb\n\t"
+               "jnz 1f\n\t"
+               "dec %%edi\n"
+               "1:"
+               : "=D" (addr), "=c" (size)
+               : "0" (addr), "1" (size), "a" (c));
+       return addr;
+}
+
+#endif /* CONFIG_X86_USE_STRING_486 */
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/xen/include/asm-x86_64/system.h b/xen/include/asm-x86_64/system.h
new file mode 100644 (file)
index 0000000..3e85277
--- /dev/null
@@ -0,0 +1,208 @@
+#ifndef __ASM_SYSTEM_H
+#define __ASM_SYSTEM_H
+
+#include <xeno/config.h>
+#include <asm/bitops.h>
+
+/* Clear and set 'TS' bit respectively */
+#define clts() __asm__ __volatile__ ("clts")
+#define stts() write_cr0(X86_CR0_TS|read_cr0())
+
+#define wbinvd() \
+       __asm__ __volatile__ ("wbinvd": : :"memory");
+
+static inline unsigned long get_limit(unsigned long segment)
+{
+       unsigned long __limit;
+       __asm__("lsll %1,%0"
+               :"=r" (__limit):"r" (segment));
+       return __limit+1;
+}
+
+#define nop() __asm__ __volatile__ ("nop")
+
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ *   but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+       switch (size) {
+               case 1:
+                       __asm__ __volatile__("xchgb %b0,%1"
+                               :"=q" (x)
+                               :"m" (*__xg(ptr)), "0" (x)
+                               :"memory");
+                       break;
+               case 2:
+                       __asm__ __volatile__("xchgw %w0,%1"
+                               :"=r" (x)
+                               :"m" (*__xg(ptr)), "0" (x)
+                               :"memory");
+                       break;
+               case 4:
+                       __asm__ __volatile__("xchgl %0,%1"
+                               :"=r" (x)
+                               :"m" (*__xg(ptr)), "0" (x)
+                               :"memory");
+                       break;
+       }
+       return x;
+}
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+                                     unsigned long new, int size)
+{
+       unsigned long prev;
+       switch (size) {
+       case 1:
+               __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+                                    : "=a"(prev)
+                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "memory");
+               return prev;
+       case 2:
+               __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+                                    : "=a"(prev)
+                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "memory");
+               return prev;
+       case 4:
+               __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
+                                    : "=a"(prev)
+                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "memory");
+               return prev;
+       }
+       return old;
+}
+
+#define cmpxchg(ptr,o,n)\
+       ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+                                       (unsigned long)(n),sizeof(*(ptr))))
+
+
+/*
+ * This function causes longword _o to be changed to _n at location _p.
+ * If this access causes a fault then we return 1, otherwise we return 0.
+ * If no fault occurs then _o is updated to teh value we saw at _p. If this
+ * is the same as the initial value of _o then _n is written to location _p.
+ */
+#define cmpxchg_user(_p,_o,_n)                                          \
+({                                                                      \
+    int _rc;                                                            \
+    __asm__ __volatile__ (                                              \
+        "1: " LOCK_PREFIX "cmpxchgl %2,%3\n"                            \
+        "2:\n"                                                          \
+        ".section .fixup,\"ax\"\n"                                      \
+        "3:     movl $1,%1\n"                                           \
+        "       jmp 2b\n"                                               \
+        ".previous\n"                                                   \
+        ".section __ex_table,\"a\"\n"                                   \
+        "       .align 4\n"                                             \
+        "       .long 1b,3b\n"                                          \
+        ".previous"                                                     \
+        : "=a" (_o), "=r" (_rc)                                         \
+        : "q" (_n), "m" (*__xg((volatile void *)_p)), "0" (_o), "1" (0) \
+        : "memory");                                                    \
+    _rc;                                                                \
+})
+
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ *
+ * For now, "wmb()" doesn't actually do anything, as all
+ * Intel CPU's follow what Intel calls a *Processor Order*,
+ * in which all writes are seen in the program order even
+ * outside the CPU.
+ *
+ * I expect future Intel CPU's to have a weaker ordering,
+ * but I'd also expect them to finally get their act together
+ * and add some real memory barriers if so.
+ *
+ * Some non intel clones support out of order store. wmb() ceases to be a
+ * nop for these.
+ */
+#define mb()   __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#define rmb()  mb()
+
+#ifdef CONFIG_X86_OOSTORE
+#define wmb()  __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#else
+#define wmb()  __asm__ __volatile__ ("": : :"memory")
+#endif
+
+#ifdef CONFIG_SMP
+#define smp_mb()       mb()
+#define smp_rmb()      rmb()
+#define smp_wmb()      wmb()
+#else
+#define smp_mb()       barrier()
+#define smp_rmb()      barrier()
+#define smp_wmb()      barrier()
+#endif
+
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+/* interrupt control.. */
+#define __save_flags(x)                __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
+#define __restore_flags(x)     __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
+#define __cli()                __asm__ __volatile__("cli": : :"memory")
+#define __sti()                        __asm__ __volatile__("sti": : :"memory")
+/* used in the idle loop; sti takes one instruction cycle to complete */
+#define safe_halt()            __asm__ __volatile__("sti; hlt": : :"memory")
+
+/* For spinlocks etc */
+#define local_irq_save(x)      __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
+#define local_irq_restore(x)   __restore_flags(x)
+#define local_irq_disable()    __cli()
+#define local_irq_enable()     __sti()
+
+#ifdef CONFIG_SMP
+
+extern void __global_cli(void);
+extern void __global_sti(void);
+extern unsigned long __global_save_flags(void);
+extern void __global_restore_flags(unsigned long);
+#define cli() __global_cli()
+#define sti() __global_sti()
+#define save_flags(x) ((x)=__global_save_flags())
+#define restore_flags(x) __global_restore_flags(x)
+
+#else
+
+#define cli() __cli()
+#define sti() __sti()
+#define save_flags(x) __save_flags(x)
+#define restore_flags(x) __restore_flags(x)
+
+#endif
+
+/*
+ * disable hlt during certain critical i/o operations
+ */
+#define HAVE_DISABLE_HLT
+void disable_hlt(void);
+void enable_hlt(void);
+
+#define BROKEN_ACPI_Sx         0x0001
+#define BROKEN_INIT_AFTER_S1   0x0002
+
+#endif
diff --git a/xen/include/asm-x86_64/time.h b/xen/include/asm-x86_64/time.h
new file mode 100644 (file)
index 0000000..40145dd
--- /dev/null
@@ -0,0 +1,23 @@
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
+ ****************************************************************************
+ * (C) 2002 - Rolf Neugebauer - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: time.h
+ *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
+ * 
+ * Environment: Xen Hypervisor
+ * Description: Architecture dependent definition of time variables
+ */
+
+#ifndef _ASM_TIME_H_
+#define _ASM_TIME_H_
+
+#include <asm/types.h>
+#include <asm/msr.h>
+
+typedef s64 s_time_t;  /* system time */
+
+extern int using_apic_timer;
+
+#endif /* _ASM_TIME_H_ */
diff --git a/xen/include/asm-x86_64/timex.h b/xen/include/asm-x86_64/timex.h
new file mode 100644 (file)
index 0000000..3eeb5d2
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * linux/include/asm-i386/timex.h
+ *
+ * i386 architecture timex specifications
+ */
+#ifndef _ASMi386_TIMEX_H
+#define _ASMi386_TIMEX_H
+
+#include <linux/config.h>
+#include <asm/msr.h>
+
+#ifdef CONFIG_MELAN
+#  define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
+#else
+#  define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
+#endif
+
+#define CLOCK_TICK_FACTOR      20      /* Factor of both 1000000 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+       (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+               << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+/*
+ * Standard way to access the cycle counter on i586+ CPUs.
+ * Currently only used on SMP.
+ *
+ * If you really have a SMP machine with i486 chips or older,
+ * compile for that, and this will just always return zero.
+ * That's ok, it just means that the nicer scheduling heuristics
+ * won't work for you.
+ *
+ * We only use the low 32 bits, and we'd simply better make sure
+ * that we reschedule before that wraps. Scheduling at least every
+ * four billion cycles just basically sounds like a good idea,
+ * regardless of how fast the machine is. 
+ */
+typedef unsigned long long cycles_t;
+
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles (void)
+{
+#ifndef CONFIG_X86_TSC
+       return 0;
+#else
+       unsigned long long ret;
+
+       rdtscll(ret);
+       return ret;
+#endif
+}
+
+extern unsigned long cpu_khz;
+
+#define vxtime_lock()          do {} while (0)
+#define vxtime_unlock()                do {} while (0)
+
+#endif
diff --git a/xen/include/asm-x86_64/types.h b/xen/include/asm-x86_64/types.h
new file mode 100644 (file)
index 0000000..2bd0f25
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef _I386_TYPES_H
+#define _I386_TYPES_H
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#include <xeno/config.h>
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* DMA addresses come in generic and 64-bit flavours.  */
+
+#ifdef CONFIG_HIGHMEM
+typedef u64 dma_addr_t;
+#else
+typedef u32 dma_addr_t;
+#endif
+typedef u64 dma64_addr_t;
+
+#endif
diff --git a/xen/include/asm-x86_64/uaccess.h b/xen/include/asm-x86_64/uaccess.h
new file mode 100644 (file)
index 0000000..ba19cfb
--- /dev/null
@@ -0,0 +1,600 @@
+#ifndef __i386_UACCESS_H
+#define __i386_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/prefetch.h>
+#include <asm/page.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+
+#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
+
+
+#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFF)
+#define USER_DS                MAKE_MM_SEG(PAGE_OFFSET)
+
+#define get_ds()       (KERNEL_DS)
+#define get_fs()       (current->addr_limit)
+#define set_fs(x)      (current->addr_limit = (x))
+
+#define segment_eq(a,b)        ((a).seg == (b).seg)
+
+extern int __verify_write(const void *, unsigned long);
+
+#define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg))
+
+/*
+ * Uhhuh, this needs 33-bit arithmetic. We have a carry..
+ */
+#define __range_ok(addr,size) ({ \
+       unsigned long flag,sum; \
+       asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \
+               :"=&r" (flag), "=r" (sum) \
+               :"1" (addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); \
+       flag; })
+
+#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
+
+static inline int verify_area(int type, const void * addr, unsigned long size)
+{
+       return access_ok(type,addr,size) ? 0 : -EFAULT;
+}
+
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+       unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ */
+
+extern void __get_user_1(void);
+extern void __get_user_2(void);
+extern void __get_user_4(void);
+
+#define __get_user_x(size,ret,x,ptr) \
+       __asm__ __volatile__("call __get_user_" #size \
+               :"=a" (ret),"=d" (x) \
+               :"0" (ptr))
+
+/* Careful: we have to cast the result to the type of the pointer for sign reasons */
+#define get_user(x,ptr)                                                        \
+({     int __ret_gu=1,__val_gu;                                                \
+       switch(sizeof (*(ptr))) {                                       \
+       case 1: __ret_gu=copy_from_user(&__val_gu,ptr,1); break;                        \
+       case 2: __ret_gu=copy_from_user(&__val_gu,ptr,2); break;                 \
+       case 4: __ret_gu=copy_from_user(&__val_gu,ptr,4); break;                 \
+       default: __ret_gu=copy_from_user(&__val_gu,ptr,8); break;                 \
+       /*case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;*/              \
+       /*case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;*/              \
+       /*case 4:  __get_user_x(4,__ret_gu,__val_gu,ptr); break;*/              \
+       /*default: __get_user_x(X,__ret_gu,__val_gu,ptr); break;*/              \
+       }                                                               \
+       (x) = (__typeof__(*(ptr)))__val_gu;                             \
+       __ret_gu;                                                       \
+})
+
+extern void __put_user_1(void);
+extern void __put_user_2(void);
+extern void __put_user_4(void);
+extern void __put_user_8(void);
+
+extern void __put_user_bad(void);
+
+#define put_user(x,ptr)                                                        \
+  __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+#define __get_user(x,ptr) \
+  __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user(x,ptr) \
+  __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+#define __put_user_nocheck(x,ptr,size)                 \
+({                                                     \
+       long __pu_err;                                  \
+       __put_user_size((x),(ptr),(size),__pu_err);     \
+       __pu_err;                                       \
+})
+
+
+#define __put_user_check(x,ptr,size)                   \
+({                                                     \
+       long __pu_err = -EFAULT;                                        \
+       __typeof__(*(ptr)) *__pu_addr = (ptr);          \
+       if (access_ok(VERIFY_WRITE,__pu_addr,size))     \
+               __put_user_size((x),__pu_addr,(size),__pu_err); \
+       __pu_err;                                       \
+})                                                     
+
+#define __put_user_u64(x, addr, err)                           \
+       __asm__ __volatile__(                                   \
+               "1:     movl %%eax,0(%2)\n"                     \
+               "2:     movl %%edx,4(%2)\n"                     \
+               "3:\n"                                          \
+               ".section .fixup,\"ax\"\n"                      \
+               "4:     movl %3,%0\n"                           \
+               "       jmp 3b\n"                               \
+               ".previous\n"                                   \
+               ".section __ex_table,\"a\"\n"                   \
+               "       .align 4\n"                             \
+               "       .long 1b,4b\n"                          \
+               "       .long 2b,4b\n"                          \
+               ".previous"                                     \
+               : "=r"(err)                                     \
+               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
+
+#define __put_user_size(x,ptr,size,retval)                             \
+do {                                                                   \
+       retval = 0;                                                     \
+       switch (size) {                                                 \
+         case 1: __put_user_asm(x,ptr,retval,"b","b","iq"); break;     \
+         case 2: __put_user_asm(x,ptr,retval,"w","w","ir"); break;     \
+         case 4: __put_user_asm(x,ptr,retval,"l","","ir"); break;      \
+         case 8: __put_user_u64(x,ptr,retval); break;                  \
+         default: __put_user_bad();                                    \
+       }                                                               \
+} while (0)
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct *)(x))
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+#define __put_user_asm(x, addr, err, itype, rtype, ltype)      \
+       __asm__ __volatile__(                                   \
+               "1:     mov"itype" %"rtype"1,%2\n"              \
+               "2:\n"                                          \
+               ".section .fixup,\"ax\"\n"                      \
+               "3:     movl %3,%0\n"                           \
+               "       jmp 2b\n"                               \
+               ".previous\n"                                   \
+               ".section __ex_table,\"a\"\n"                   \
+               "       .align 4\n"                             \
+               "       .long 1b,3b\n"                          \
+               ".previous"                                     \
+               : "=r"(err)                                     \
+               : ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err))
+
+
+#define __get_user_nocheck(x,ptr,size)                         \
+({                                                             \
+       long __gu_err, __gu_val;                                \
+       __get_user_size(__gu_val,(ptr),(size),__gu_err);        \
+       (x) = (__typeof__(*(ptr)))__gu_val;                     \
+       __gu_err;                                               \
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_size(x,ptr,size,retval)                             \
+do {                                                                   \
+       retval = 0;                                                     \
+       switch (size) {                                                 \
+         case 1: __get_user_asm(x,ptr,retval,"b","b","=q"); break;     \
+         case 2: __get_user_asm(x,ptr,retval,"w","w","=r"); break;     \
+         case 4: __get_user_asm(x,ptr,retval,"l","","=r"); break;      \
+         default: (x) = __get_user_bad();                              \
+       }                                                               \
+} while (0)
+
+#define __get_user_asm(x, addr, err, itype, rtype, ltype)      \
+       __asm__ __volatile__(                                   \
+               "1:     mov"itype" %2,%"rtype"1\n"              \
+               "2:\n"                                          \
+               ".section .fixup,\"ax\"\n"                      \
+               "3:     movl %3,%0\n"                           \
+               "       xor"itype" %"rtype"1,%"rtype"1\n"       \
+               "       jmp 2b\n"                               \
+               ".previous\n"                                   \
+               ".section __ex_table,\"a\"\n"                   \
+               "       .align 4\n"                             \
+               "       .long 1b,3b\n"                          \
+               ".previous"                                     \
+               : "=r"(err), ltype (x)                          \
+               : "m"(__m(addr)), "i"(-EFAULT), "0"(err))
+
+
+/*
+ * Copy To/From Userspace
+ */
+
+/* Generic arbitrary sized copy.  */
+#define __copy_user(to,from,size)                                      \
+do {                                                                   \
+       int __d0, __d1;                                                 \
+       __asm__ __volatile__(                                           \
+               "0:     rep; movsl\n"                                   \
+               "       movl %3,%0\n"                                   \
+               "1:     rep; movsb\n"                                   \
+               "2:\n"                                                  \
+               ".section .fixup,\"ax\"\n"                              \
+               "3:     lea 0(%3,%0,4),%0\n"                            \
+               "       jmp 2b\n"                                       \
+               ".previous\n"                                           \
+               ".section __ex_table,\"a\"\n"                           \
+               "       .align 4\n"                                     \
+               "       .long 0b,3b\n"                                  \
+               "       .long 1b,2b\n"                                  \
+               ".previous"                                             \
+               : "=&c"(size), "=&D" (__d0), "=&S" (__d1)               \
+               : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)      \
+               : "memory");                                            \
+} while (0)
+
+#define __copy_user_zeroing(to,from,size)                              \
+do {                                                                   \
+       int __d0, __d1;                                                 \
+       __asm__ __volatile__(                                           \
+               "0:     rep; movsl\n"                                   \
+               "       movl %3,%0\n"                                   \
+               "1:     rep; movsb\n"                                   \
+               "2:\n"                                                  \
+               ".section .fixup,\"ax\"\n"                              \
+               "3:     lea 0(%3,%0,4),%0\n"                            \
+               "4:     pushl %0\n"                                     \
+               "       pushl %%eax\n"                                  \
+               "       xorl %%eax,%%eax\n"                             \
+               "       rep; stosb\n"                                   \
+               "       popl %%eax\n"                                   \
+               "       popl %0\n"                                      \
+               "       jmp 2b\n"                                       \
+               ".previous\n"                                           \
+               ".section __ex_table,\"a\"\n"                           \
+               "       .align 4\n"                                     \
+               "       .long 0b,3b\n"                                  \
+               "       .long 1b,4b\n"                                  \
+               ".previous"                                             \
+               : "=&c"(size), "=&D" (__d0), "=&S" (__d1)               \
+               : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)      \
+               : "memory");                                            \
+} while (0)
+
+/* We let the __ versions of copy_from/to_user inline, because they're often
+ * used in fast paths and have only a small space overhead.
+ */
+static inline unsigned long
+__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
+{
+       __copy_user_zeroing(to,from,n);
+       return n;
+}
+
+static inline unsigned long
+__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
+{
+       __copy_user(to,from,n);
+       return n;
+}
+
+
+/* Optimize just a little bit when we know the size of the move. */
+#define __constant_copy_user(to, from, size)                   \
+do {                                                           \
+       int __d0, __d1;                                         \
+       switch (size & 3) {                                     \
+       default:                                                \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "2:     shl $2,%0\n"                    \
+                       "       jmp 1b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,2b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       case 1:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsb\n"                        \
+                       "2:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "3:     shl $2,%0\n"                    \
+                       "4:     incl %0\n"                      \
+                       "       jmp 2b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,3b\n"                  \
+                       "       .long 1b,4b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       case 2:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsw\n"                        \
+                       "2:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "3:     shl $2,%0\n"                    \
+                       "4:     addl $2,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,3b\n"                  \
+                       "       .long 1b,4b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       case 3:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsw\n"                        \
+                       "2:     movsb\n"                        \
+                       "3:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "4:     shl $2,%0\n"                    \
+                       "5:     addl $2,%0\n"                   \
+                       "6:     incl %0\n"                      \
+                       "       jmp 3b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,4b\n"                  \
+                       "       .long 1b,5b\n"                  \
+                       "       .long 2b,6b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       }                                                       \
+} while (0)
+
+/* Optimize just a little bit when we know the size of the move. */
+#define __constant_copy_user_zeroing(to, from, size)           \
+do {                                                           \
+       int __d0, __d1;                                         \
+       switch (size & 3) {                                     \
+       default:                                                \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "2:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       jmp 1b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,2b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       case 1:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsb\n"                        \
+                       "2:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "3:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       incl %0\n"                      \
+                       "       jmp 2b\n"                       \
+                       "4:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       incl %0\n"                      \
+                       "       jmp 2b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,3b\n"                  \
+                       "       .long 1b,4b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       case 2:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsw\n"                        \
+                       "2:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "3:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       stosw\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       addl $2,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       "4:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosw\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       addl $2,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,3b\n"                  \
+                       "       .long 1b,4b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       case 3:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsw\n"                        \
+                       "2:     movsb\n"                        \
+                       "3:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "4:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       stosw\n"                        \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       addl $3,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       "5:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosw\n"                        \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       addl $3,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       "6:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       incl %0\n"                      \
+                       "       jmp 3b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,4b\n"                  \
+                       "       .long 1b,5b\n"                  \
+                       "       .long 2b,6b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
+               break;                                          \
+       }                                                       \
+} while (0)
+
+unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
+unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
+
+static inline unsigned long
+__constant_copy_to_user(void *to, const void *from, unsigned long n)
+{
+       prefetch(from);
+       if (access_ok(VERIFY_WRITE, to, n))
+               __constant_copy_user(to,from,n);
+       return n;
+}
+
+static inline unsigned long
+__constant_copy_from_user(void *to, const void *from, unsigned long n)
+{
+       if (access_ok(VERIFY_READ, from, n))
+               __constant_copy_user_zeroing(to,from,n);
+       else
+               memset(to, 0, n);
+       return n;
+}
+
+static inline unsigned long
+__constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
+{
+       __constant_copy_user(to,from,n);
+       return n;
+}
+
+static inline unsigned long
+__constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
+{
+       __constant_copy_user_zeroing(to,from,n);
+       return n;
+}
+
+#define copy_to_user(to,from,n)                                \
+       (__builtin_constant_p(n) ?                      \
+        __constant_copy_to_user((to),(from),(n)) :     \
+        __generic_copy_to_user((to),(from),(n)))
+
+#define copy_from_user(to,from,n)                      \
+       (__builtin_constant_p(n) ?                      \
+        __constant_copy_from_user((to),(from),(n)) :   \
+        __generic_copy_from_user((to),(from),(n)))
+
+#define __copy_to_user(to,from,n)                      \
+       (__builtin_constant_p(n) ?                      \
+        __constant_copy_to_user_nocheck((to),(from),(n)) :     \
+        __generic_copy_to_user_nocheck((to),(from),(n)))
+
+#define __copy_from_user(to,from,n)                    \
+       (__builtin_constant_p(n) ?                      \
+        __constant_copy_from_user_nocheck((to),(from),(n)) :   \
+        __generic_copy_from_user_nocheck((to),(from),(n)))
+
+long strncpy_from_user(char *dst, const char *src, long count);
+long __strncpy_from_user(char *dst, const char *src, long count);
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+long strnlen_user(const char *str, long n);
+unsigned long clear_user(void *mem, unsigned long len);
+unsigned long __clear_user(void *mem, unsigned long len);
+
+#endif /* __i386_UACCESS_H */
diff --git a/xen/include/asm-x86_64/unaligned.h b/xen/include/asm-x86_64/unaligned.h
new file mode 100644 (file)
index 0000000..7acd795
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef __I386_UNALIGNED_H
+#define __I386_UNALIGNED_H
+
+/*
+ * The i386 can do unaligned accesses itself. 
+ *
+ * The strange macros are there to make sure these can't
+ * be misused in a way that makes them not work on other
+ * architectures where unaligned accesses aren't as simple.
+ */
+
+/**
+ * get_unaligned - get value from possibly mis-aligned location
+ * @ptr: pointer to value
+ *
+ * This macro should be used for accessing values larger in size than 
+ * single bytes at locations that are expected to be improperly aligned, 
+ * e.g. retrieving a u16 value from a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define get_unaligned(ptr) (*(ptr))
+
+/**
+ * put_unaligned - put value to a possibly mis-aligned location
+ * @val: value to place
+ * @ptr: pointer to location
+ *
+ * This macro should be used for placing values larger in size than 
+ * single bytes at locations that are expected to be improperly aligned, 
+ * e.g. writing a u16 value to a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+
+#endif
diff --git a/xen/include/hypervisor-ifs/if-i386/hypervisor-if-arch.h b/xen/include/hypervisor-ifs/if-i386/hypervisor-if-arch.h
new file mode 100644 (file)
index 0000000..ee950c0
--- /dev/null
@@ -0,0 +1,352 @@
+/******************************************************************************
+ * hypervisor-if.h
+ * 
+ * Interface to Xeno hypervisor.
+ */
+
+#ifndef __HYPERVISOR_IF_H__
+#define __HYPERVISOR_IF_H__
+
+/*
+ * SEGMENT DESCRIPTOR TABLES
+ */
+/*
+ * A number of GDT entries are reserved by Xen. These are not situated at the
+ * start of the GDT because some stupid OSes export hard-coded selector values
+ * in their ABI. These hard-coded values are always near the start of the GDT,
+ * so Xen places itself out of the way.
+ * 
+ * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
+ * and LAST_RESERVED_GDT_ENTRY are reserved).
+ */
+#define NR_RESERVED_GDT_ENTRIES    40
+#define FIRST_RESERVED_GDT_ENTRY   256
+#define LAST_RESERVED_GDT_ENTRY    \
+  (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
+
+/*
+ * These flat segments are in the Xen-private section of every GDT. Since these
+ * are also present in the initial GDT, many OSes will be able to avoid
+ * installing their own GDT.
+ */
+#define FLAT_RING1_CS 0x0819    /* GDT index 259 */
+#define FLAT_RING1_DS 0x0821    /* GDT index 260 */
+#define FLAT_RING3_CS 0x082b    /* GDT index 261 */
+#define FLAT_RING3_DS 0x0833    /* GDT index 262 */
+
+
+/*
+ * HYPERVISOR "SYSTEM CALLS"
+ */
+
+/* EAX = vector; EBX, ECX, EDX, ESI, EDI = args 1, 2, 3, 4, 5. */
+#define __HYPERVISOR_set_trap_table        0
+#define __HYPERVISOR_mmu_update            1
+#define __HYPERVISOR_console_write         2 /* DEPRECATED */
+#define __HYPERVISOR_set_gdt               3
+#define __HYPERVISOR_stack_switch          4
+#define __HYPERVISOR_set_callbacks         5
+#define __HYPERVISOR_net_io_op             6
+#define __HYPERVISOR_fpu_taskswitch        7
+#define __HYPERVISOR_sched_op              8
+#define __HYPERVISOR_dom0_op               9
+#define __HYPERVISOR_network_op           10
+#define __HYPERVISOR_block_io_op          11
+#define __HYPERVISOR_set_debugreg         12
+#define __HYPERVISOR_get_debugreg         13
+#define __HYPERVISOR_update_descriptor    14
+#define __HYPERVISOR_set_fast_trap        15
+#define __HYPERVISOR_dom_mem_op           16
+#define __HYPERVISOR_multicall            17
+#define __HYPERVISOR_kbd_op               18
+#define __HYPERVISOR_update_va_mapping    19
+#define __HYPERVISOR_set_timer_op         20
+#define __HYPERVISOR_event_channel_op     21
+#define __HYPERVISOR_xen_version          22
+#define __HYPERVISOR_serial_io            23
+
+/* And the trap vector is... */
+#define TRAP_INSTR "int $0x82"
+
+
+/*
+ * MULTICALLS
+ * 
+ * Multicalls are listed in an array, with each element being a fixed size 
+ * (BYTES_PER_MULTICALL_ENTRY). Each is of the form (op, arg1, ..., argN)
+ * where each element of the tuple is a machine word. 
+ */
+#define BYTES_PER_MULTICALL_ENTRY 32
+
+
+/* EVENT MESSAGES
+ *
+ * Here, as in the interrupts to the guestos, additional network interfaces
+ * are defined.         These definitions server as placeholders for the event bits,
+ * however, in the code these events will allways be referred to as shifted
+ * offsets from the base NET events.
+ */
+
+/* Events that a guest OS may receive from the hypervisor. */
+#define EVENT_BLKDEV   0x01 /* A block device response has been queued. */
+#define EVENT_TIMER    0x02 /* A timeout has been updated. */
+#define EVENT_DIE      0x04 /* OS is about to be killed. Clean up please! */
+#define EVENT_DEBUG    0x08 /* Request guest to dump debug info (gross!) */
+#define EVENT_NET      0x10 /* There are packets for transmission. */
+#define EVENT_PS2      0x20 /* PS/2 keyboard or mouse event(s) */
+#define EVENT_STOP     0x40 /* Prepare for stopping and possible pickling */
+#define EVENT_EVTCHN   0x80 /* Event pending on an event channel */
+#define EVENT_VBD_UPD  0x100 /* Event to signal VBDs should be reprobed */
+
+/* Bit offsets, as opposed to the above masks. */
+#define _EVENT_BLKDEV   0
+#define _EVENT_TIMER    1
+#define _EVENT_DIE      2
+#define _EVENT_DEBUG    3
+#define _EVENT_NET      4
+#define _EVENT_PS2      5
+#define _EVENT_STOP     6
+#define _EVENT_EVTCHN   7
+#define _EVENT_VBD_UPD  8
+#define _EVENT_CONSOLE  9 /* This is only for domain-0 initial console. */
+
+/*
+ * Virtual addresses beyond this are not modifiable by guest OSes. The 
+ * machine->physical mapping table starts at this address, read-only.
+ */
+#define HYPERVISOR_VIRT_START (0xFC000000UL)
+#ifndef machine_to_phys_mapping
+#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
+#endif
+
+
+/*
+ * MMU_XXX: specified in least 2 bits of 'ptr' field. These bits are masked
+ *  off to get the real 'ptr' value.
+ * All requests specify relevent address in 'ptr'. This is either a
+ * machine/physical address (MA), or linear/virtual address (VA).
+ * Normal requests specify update value in 'value'.
+ * Extended requests specify command in least 8 bits of 'value'. These bits
+ *  are masked off to get the real 'val' value. Except for MMUEXT_SET_LDT 
+ *  which shifts the least bits out.
+ */
+/* A normal page-table update request. */
+#define MMU_NORMAL_PT_UPDATE     0 /* checked '*ptr = val'. ptr is MA.       */
+/* Update an entry in the machine->physical mapping table. */
+#define MMU_MACHPHYS_UPDATE      2 /* ptr = MA of frame to modify entry for  */
+/* An extended command. */
+#define MMU_EXTENDED_COMMAND     3 /* least 8 bits of val demux further      */
+/* Extended commands: */
+#define MMUEXT_PIN_L1_TABLE      0 /* ptr = MA of frame to pin               */
+#define MMUEXT_PIN_L2_TABLE      1 /* ptr = MA of frame to pin               */
+#define MMUEXT_PIN_L3_TABLE      2 /* ptr = MA of frame to pin               */
+#define MMUEXT_PIN_L4_TABLE      3 /* ptr = MA of frame to pin               */
+#define MMUEXT_UNPIN_TABLE       4 /* ptr = MA of frame to unpin             */
+#define MMUEXT_NEW_BASEPTR       5 /* ptr = MA of new pagetable base         */
+#define MMUEXT_TLB_FLUSH         6 /* ptr = NULL                             */
+#define MMUEXT_INVLPG            7 /* ptr = NULL ; val = VA to invalidate    */
+#define MMUEXT_SET_LDT           8 /* ptr = VA of table; val = # entries     */
+/* NB. MMUEXT_SET_SUBJECTDOM must consist of *_L followed immediately by *_H */
+#define MMUEXT_SET_SUBJECTDOM_L  9 /* (ptr[31:15],val[31:15]) = dom[31:0]    */
+#define MMUEXT_SET_SUBJECTDOM_H 10 /* (ptr[31:15],val[31:15]) = dom[63:32]   */
+#define MMUEXT_CMD_MASK        255
+#define MMUEXT_CMD_SHIFT         8
+
+/* These are passed as 'flags' to update_va_mapping. They can be ORed. */
+#define UVMF_FLUSH_TLB          1 /* Flush entire TLB. */
+#define UVMF_INVLPG             2 /* Flush the VA mapping being updated. */
+
+/*
+ * Master "switch" for enabling/disabling event delivery.
+ */
+#define EVENTS_MASTER_ENABLE_MASK 0x80000000UL
+#define EVENTS_MASTER_ENABLE_BIT  31
+
+
+/*
+ * SCHEDOP_* - Scheduler hypercall operations.
+ */
+#define SCHEDOP_yield           0   /* Give up the CPU voluntarily.      */
+#define SCHEDOP_block           1   /* Block until an event is received. */
+#define SCHEDOP_exit            3   /* Exit and kill this domain.        */
+#define SCHEDOP_stop            4   /* Stop executing this domain.       */
+
+/*
+ * Commands to HYPERVISOR_serial_io().
+ */
+#define SERIALIO_write          0
+#define SERIALIO_read           1
+
+#ifndef __ASSEMBLY__
+
+typedef u64 domid_t;
+/* DOMID_SELF is used in certain contexts to refer to oneself. */
+#define DOMID_SELF (~1ULL)
+
+#include "network.h"
+#include "block.h"
+
+/*
+ * Send an array of these to HYPERVISOR_set_trap_table()
+ */
+#define TI_GET_DPL(_ti)      ((_ti)->flags & 3)
+#define TI_GET_IF(_ti)       ((_ti)->flags & 4)
+#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
+#define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
+typedef struct trap_info_st
+{
+    unsigned char  vector;  /* exception vector                              */
+    unsigned char  flags;   /* 0-3: privilege level; 4: clear event enable?  */
+    unsigned short cs;     /* code selector                                 */
+    unsigned long  address; /* code address                                  */
+} trap_info_t;
+
+/*
+ * Send an array of these to HYPERVISOR_mmu_update()
+ */
+typedef struct
+{
+    unsigned long ptr, val; /* *ptr = val */
+} mmu_update_t;
+
+/*
+ * Send an array of these to HYPERVISOR_multicall()
+ */
+typedef struct
+{
+    unsigned long op;
+    unsigned long args[7];
+} multicall_entry_t;
+
+typedef struct
+{
+    unsigned long ebx;
+    unsigned long ecx;
+    unsigned long edx;
+    unsigned long esi;
+    unsigned long edi;
+    unsigned long ebp;
+    unsigned long eax;
+    unsigned long ds;
+    unsigned long es;
+    unsigned long fs;
+    unsigned long gs;
+    unsigned long _unused;
+    unsigned long eip;
+    unsigned long cs;
+    unsigned long eflags;
+    unsigned long esp;
+    unsigned long ss;
+} execution_context_t;
+
+/*
+ * Xen/guestos shared data -- pointer provided in start_info.
+ * NB. We expect that this struct is smaller than a page.
+ */
+typedef struct shared_info_st {
+
+    /* Bitmask of outstanding event notifications hypervisor -> guest OS. */
+    unsigned long events;
+    /*
+     * Hypervisor will only signal event delivery via the "callback exception"
+     * when a pending event is not masked. The mask also contains a "master
+     * enable" which prevents any event delivery. This mask can be used to
+     * prevent unbounded reentrancy and stack overflow (in this way, acts as a
+     * kind of interrupt-enable flag).
+     */
+    unsigned long events_mask;
+
+    /*
+     * A domain can have up to 1024 bidirectional event channels to/from other
+     * domains. Domains must agree out-of-band to set up a connection, and then
+     * each must explicitly request a connection to the other. When both have
+     * made the request the channel is fully allocated and set up.
+     * 
+     * An event channel is a single sticky 'bit' of information. Setting the
+     * sticky bit also causes an upcall into the target domain. In this way
+     * events can be seen as an IPI [Inter-Process(or) Interrupt].
+     * 
+     * A guest can see which of its event channels are pending by reading the
+     * 'event_channel_pend' bitfield. To avoid a linear scan of the entire
+     * bitfield there is a 'selector' which indicates which words in the
+     * bitfield contain at least one set bit.
+     * 
+     * There is a similar bitfield to indicate which event channels have been
+     * disconnected by the remote end. There is also a 'selector' for this
+     * field.
+     */
+    u32 event_channel_pend[32];
+    u32 event_channel_pend_sel;
+    u32 event_channel_disc[32];
+    u32 event_channel_disc_sel;
+
+    /*
+     * Time: The following abstractions are exposed: System Time, Clock Time,
+     * Domain Virtual Time. Domains can access Cycle counter time directly.
+     */
+
+    unsigned int       rdtsc_bitshift;  /* tsc_timestamp uses N:N+31 of TSC. */
+    u64                cpu_freq;        /* CPU frequency (Hz).               */
+
+    /*
+     * The following values are updated periodically (and not necessarily
+     * atomically!). The guest OS detects this because 'time_version1' is
+     * incremented just before updating these values, and 'time_version2' is
+     * incremented immediately after. See Xenolinux code for an example of how 
+     * to read these values safely (arch/xeno/kernel/time.c).
+     */
+    unsigned long      time_version1;   /* A version number for info below.  */
+    unsigned long      time_version2;   /* A version number for info below.  */
+    unsigned long      tsc_timestamp;   /* TSC at last update of time vals.  */
+    u64                system_time;     /* Time, in nanosecs, since boot.    */
+    unsigned long      wc_sec;          /* Secs  00:00:00 UTC, Jan 1, 1970.  */
+    unsigned long      wc_usec;         /* Usecs 00:00:00 UTC, Jan 1, 1970.  */
+    
+    /* Domain Virtual Time */
+    u64                domain_time;
+       
+    /*
+     * Timeout values:
+     * Allow a domain to specify a timeout value in system time and 
+     * domain virtual time.
+     */
+    u64                wall_timeout;
+    u64                domain_timeout;
+
+    /*
+     * The index structures are all stored here for convenience. The rings 
+     * themselves are allocated by Xen but the guestos must create its own 
+     * mapping -- the machine address is given in the startinfo structure to 
+     * allow this to happen.
+     */
+    net_idx_t net_idx[MAX_DOMAIN_VIFS];
+
+    execution_context_t execution_context;
+
+} shared_info_t;
+
+/*
+ * NB. We expect that this struct is smaller than a page.
+ */
+typedef struct start_info_st {
+    /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME.     */
+    unsigned long nr_pages;      /* total pages allocated to this domain. */
+    unsigned long shared_info;   /* MACHINE address of shared info struct.*/
+    unsigned long flags;          /* SIF_xxx flags.                        */
+    /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME).      */
+    unsigned long pt_base;       /* VIRTUAL address of page directory.    */
+    unsigned long mod_start;     /* VIRTUAL address of pre-loaded module. */
+    unsigned long mod_len;       /* Size (bytes) of pre-loaded module.    */
+    unsigned char cmd_line[1];   /* Variable-length options.              */
+} start_info_t;
+
+/* These flags are passed in the 'flags' field of start_info_t. */
+#define SIF_PRIVILEGED 1          /* Is the domain privileged? */
+#define SIF_INITDOMAIN 2          /* Is thsi the initial control domain? */
+
+/* For use in guest OSes. */
+extern shared_info_t *HYPERVISOR_shared_info;
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __HYPERVISOR_IF_H__ */
diff --git a/xen/include/hypervisor-ifs/if-x86_64/hypervisor-if-arch.h b/xen/include/hypervisor-ifs/if-x86_64/hypervisor-if-arch.h
new file mode 100644 (file)
index 0000000..ee950c0
--- /dev/null
@@ -0,0 +1,352 @@
+/******************************************************************************
+ * hypervisor-if.h
+ * 
+ * Interface to Xeno hypervisor.
+ */
+
+#ifndef __HYPERVISOR_IF_H__
+#define __HYPERVISOR_IF_H__
+
+/*
+ * SEGMENT DESCRIPTOR TABLES
+ */
+/*
+ * A number of GDT entries are reserved by Xen. These are not situated at the
+ * start of the GDT because some stupid OSes export hard-coded selector values
+ * in their ABI. These hard-coded values are always near the start of the GDT,
+ * so Xen places itself out of the way.
+ * 
+ * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
+ * and LAST_RESERVED_GDT_ENTRY are reserved).
+ */
+#define NR_RESERVED_GDT_ENTRIES    40
+#define FIRST_RESERVED_GDT_ENTRY   256
+#define LAST_RESERVED_GDT_ENTRY    \
+  (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
+
+/*
+ * These flat segments are in the Xen-private section of every GDT. Since these
+ * are also present in the initial GDT, many OSes will be able to avoid
+ * installing their own GDT.
+ */
+#define FLAT_RING1_CS 0x0819    /* GDT index 259 */
+#define FLAT_RING1_DS 0x0821    /* GDT index 260 */
+#define FLAT_RING3_CS 0x082b    /* GDT index 261 */
+#define FLAT_RING3_DS 0x0833    /* GDT index 262 */
+
+
+/*
+ * HYPERVISOR "SYSTEM CALLS"
+ */
+
+/* EAX = vector; EBX, ECX, EDX, ESI, EDI = args 1, 2, 3, 4, 5. */
+#define __HYPERVISOR_set_trap_table        0
+#define __HYPERVISOR_mmu_update            1
+#define __HYPERVISOR_console_write         2 /* DEPRECATED */
+#define __HYPERVISOR_set_gdt               3
+#define __HYPERVISOR_stack_switch          4
+#define __HYPERVISOR_set_callbacks         5
+#define __HYPERVISOR_net_io_op             6
+#define __HYPERVISOR_fpu_taskswitch        7
+#define __HYPERVISOR_sched_op              8
+#define __HYPERVISOR_dom0_op               9
+#define __HYPERVISOR_network_op           10
+#define __HYPERVISOR_block_io_op          11
+#define __HYPERVISOR_set_debugreg         12
+#define __HYPERVISOR_get_debugreg         13
+#define __HYPERVISOR_update_descriptor    14
+#define __HYPERVISOR_set_fast_trap        15
+#define __HYPERVISOR_dom_mem_op           16
+#define __HYPERVISOR_multicall            17
+#define __HYPERVISOR_kbd_op               18
+#define __HYPERVISOR_update_va_mapping    19
+#define __HYPERVISOR_set_timer_op         20
+#define __HYPERVISOR_event_channel_op     21
+#define __HYPERVISOR_xen_version          22
+#define __HYPERVISOR_serial_io            23
+
+/* And the trap vector is... */
+#define TRAP_INSTR "int $0x82"
+
+
+/*
+ * MULTICALLS
+ * 
+ * Multicalls are listed in an array, with each element being a fixed size 
+ * (BYTES_PER_MULTICALL_ENTRY). Each is of the form (op, arg1, ..., argN)
+ * where each element of the tuple is a machine word. 
+ */
+#define BYTES_PER_MULTICALL_ENTRY 32
+
+
+/* EVENT MESSAGES
+ *
+ * Here, as in the interrupts to the guestos, additional network interfaces
+ * are defined.         These definitions server as placeholders for the event bits,
+ * however, in the code these events will allways be referred to as shifted
+ * offsets from the base NET events.
+ */
+
+/* Events that a guest OS may receive from the hypervisor. */
+#define EVENT_BLKDEV   0x01 /* A block device response has been queued. */
+#define EVENT_TIMER    0x02 /* A timeout has been updated. */
+#define EVENT_DIE      0x04 /* OS is about to be killed. Clean up please! */
+#define EVENT_DEBUG    0x08 /* Request guest to dump debug info (gross!) */
+#define EVENT_NET      0x10 /* There are packets for transmission. */
+#define EVENT_PS2      0x20 /* PS/2 keyboard or mouse event(s) */
+#define EVENT_STOP     0x40 /* Prepare for stopping and possible pickling */
+#define EVENT_EVTCHN   0x80 /* Event pending on an event channel */
+#define EVENT_VBD_UPD  0x100 /* Event to signal VBDs should be reprobed */
+
+/* Bit offsets, as opposed to the above masks. */
+#define _EVENT_BLKDEV   0
+#define _EVENT_TIMER    1
+#define _EVENT_DIE      2
+#define _EVENT_DEBUG    3
+#define _EVENT_NET      4
+#define _EVENT_PS2      5
+#define _EVENT_STOP     6
+#define _EVENT_EVTCHN   7
+#define _EVENT_VBD_UPD  8
+#define _EVENT_CONSOLE  9 /* This is only for domain-0 initial console. */
+
+/*
+ * Virtual addresses beyond this are not modifiable by guest OSes. The 
+ * machine->physical mapping table starts at this address, read-only.
+ */
+#define HYPERVISOR_VIRT_START (0xFC000000UL)
+#ifndef machine_to_phys_mapping
+#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
+#endif
+
+
+/*
+ * MMU_XXX: specified in least 2 bits of 'ptr' field. These bits are masked
+ *  off to get the real 'ptr' value.
+ * All requests specify relevent address in 'ptr'. This is either a
+ * machine/physical address (MA), or linear/virtual address (VA).
+ * Normal requests specify update value in 'value'.
+ * Extended requests specify command in least 8 bits of 'value'. These bits
+ *  are masked off to get the real 'val' value. Except for MMUEXT_SET_LDT 
+ *  which shifts the least bits out.
+ */
+/* A normal page-table update request. */
+#define MMU_NORMAL_PT_UPDATE     0 /* checked '*ptr = val'. ptr is MA.       */
+/* Update an entry in the machine->physical mapping table. */
+#define MMU_MACHPHYS_UPDATE      2 /* ptr = MA of frame to modify entry for  */
+/* An extended command. */
+#define MMU_EXTENDED_COMMAND     3 /* least 8 bits of val demux further      */
+/* Extended commands: */
+#define MMUEXT_PIN_L1_TABLE      0 /* ptr = MA of frame to pin               */
+#define MMUEXT_PIN_L2_TABLE      1 /* ptr = MA of frame to pin               */
+#define MMUEXT_PIN_L3_TABLE      2 /* ptr = MA of frame to pin               */
+#define MMUEXT_PIN_L4_TABLE      3 /* ptr = MA of frame to pin               */
+#define MMUEXT_UNPIN_TABLE       4 /* ptr = MA of frame to unpin             */
+#define MMUEXT_NEW_BASEPTR       5 /* ptr = MA of new pagetable base         */
+#define MMUEXT_TLB_FLUSH         6 /* ptr = NULL                             */
+#define MMUEXT_INVLPG            7 /* ptr = NULL ; val = VA to invalidate    */
+#define MMUEXT_SET_LDT           8 /* ptr = VA of table; val = # entries     */
+/* NB. MMUEXT_SET_SUBJECTDOM must consist of *_L followed immediately by *_H */
+#define MMUEXT_SET_SUBJECTDOM_L  9 /* (ptr[31:15],val[31:15]) = dom[31:0]    */
+#define MMUEXT_SET_SUBJECTDOM_H 10 /* (ptr[31:15],val[31:15]) = dom[63:32]   */
+#define MMUEXT_CMD_MASK        255
+#define MMUEXT_CMD_SHIFT         8
+
+/* These are passed as 'flags' to update_va_mapping. They can be ORed. */
+#define UVMF_FLUSH_TLB          1 /* Flush entire TLB. */
+#define UVMF_INVLPG             2 /* Flush the VA mapping being updated. */
+
+/*
+ * Master "switch" for enabling/disabling event delivery.
+ */
+#define EVENTS_MASTER_ENABLE_MASK 0x80000000UL
+#define EVENTS_MASTER_ENABLE_BIT  31
+
+
+/*
+ * SCHEDOP_* - Scheduler hypercall operations.
+ */
+#define SCHEDOP_yield           0   /* Give up the CPU voluntarily.      */
+#define SCHEDOP_block           1   /* Block until an event is received. */
+#define SCHEDOP_exit            3   /* Exit and kill this domain.        */
+#define SCHEDOP_stop            4   /* Stop executing this domain.       */
+
+/*
+ * Commands to HYPERVISOR_serial_io().
+ */
+#define SERIALIO_write          0
+#define SERIALIO_read           1
+
+#ifndef __ASSEMBLY__
+
+typedef u64 domid_t;
+/* DOMID_SELF is used in certain contexts to refer to oneself. */
+#define DOMID_SELF (~1ULL)
+
+#include "network.h"
+#include "block.h"
+
+/*
+ * Send an array of these to HYPERVISOR_set_trap_table()
+ */
+#define TI_GET_DPL(_ti)      ((_ti)->flags & 3)
+#define TI_GET_IF(_ti)       ((_ti)->flags & 4)
+#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
+#define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
+typedef struct trap_info_st
+{
+    unsigned char  vector;  /* exception vector                              */
+    unsigned char  flags;   /* 0-3: privilege level; 4: clear event enable?  */
+    unsigned short cs;     /* code selector                                 */
+    unsigned long  address; /* code address                                  */
+} trap_info_t;
+
+/*
+ * Send an array of these to HYPERVISOR_mmu_update()
+ */
+typedef struct
+{
+    unsigned long ptr, val; /* *ptr = val */
+} mmu_update_t;
+
+/*
+ * Send an array of these to HYPERVISOR_multicall()
+ */
+typedef struct
+{
+    unsigned long op;
+    unsigned long args[7];
+} multicall_entry_t;
+
+typedef struct
+{
+    unsigned long ebx;
+    unsigned long ecx;
+    unsigned long edx;
+    unsigned long esi;
+    unsigned long edi;
+    unsigned long ebp;
+    unsigned long eax;
+    unsigned long ds;
+    unsigned long es;
+    unsigned long fs;
+    unsigned long gs;
+    unsigned long _unused;
+    unsigned long eip;
+    unsigned long cs;
+    unsigned long eflags;
+    unsigned long esp;
+    unsigned long ss;
+} execution_context_t;
+
+/*
+ * Xen/guestos shared data -- pointer provided in start_info.
+ * NB. We expect that this struct is smaller than a page.
+ */
+typedef struct shared_info_st {
+
+    /* Bitmask of outstanding event notifications hypervisor -> guest OS. */
+    unsigned long events;
+    /*
+     * Hypervisor will only signal event delivery via the "callback exception"
+     * when a pending event is not masked. The mask also contains a "master
+     * enable" which prevents any event delivery. This mask can be used to
+     * prevent unbounded reentrancy and stack overflow (in this way, acts as a
+     * kind of interrupt-enable flag).
+     */
+    unsigned long events_mask;
+
+    /*
+     * A domain can have up to 1024 bidirectional event channels to/from other
+     * domains. Domains must agree out-of-band to set up a connection, and then
+     * each must explicitly request a connection to the other. When both have
+     * made the request the channel is fully allocated and set up.
+     * 
+     * An event channel is a single sticky 'bit' of information. Setting the
+     * sticky bit also causes an upcall into the target domain. In this way
+     * events can be seen as an IPI [Inter-Process(or) Interrupt].
+     * 
+     * A guest can see which of its event channels are pending by reading the
+     * 'event_channel_pend' bitfield. To avoid a linear scan of the entire
+     * bitfield there is a 'selector' which indicates which words in the
+     * bitfield contain at least one set bit.
+     * 
+     * There is a similar bitfield to indicate which event channels have been
+     * disconnected by the remote end. There is also a 'selector' for this
+     * field.
+     */
+    u32 event_channel_pend[32];
+    u32 event_channel_pend_sel;
+    u32 event_channel_disc[32];
+    u32 event_channel_disc_sel;
+
+    /*
+     * Time: The following abstractions are exposed: System Time, Clock Time,
+     * Domain Virtual Time. Domains can access Cycle counter time directly.
+     */
+
+    unsigned int       rdtsc_bitshift;  /* tsc_timestamp uses N:N+31 of TSC. */
+    u64                cpu_freq;        /* CPU frequency (Hz).               */
+
+    /*
+     * The following values are updated periodically (and not necessarily
+     * atomically!). The guest OS detects this because 'time_version1' is
+     * incremented just before updating these values, and 'time_version2' is
+     * incremented immediately after. See Xenolinux code for an example of how 
+     * to read these values safely (arch/xeno/kernel/time.c).
+     */
+    unsigned long      time_version1;   /* A version number for info below.  */
+    unsigned long      time_version2;   /* A version number for info below.  */
+    unsigned long      tsc_timestamp;   /* TSC at last update of time vals.  */
+    u64                system_time;     /* Time, in nanosecs, since boot.    */
+    unsigned long      wc_sec;          /* Secs  00:00:00 UTC, Jan 1, 1970.  */
+    unsigned long      wc_usec;         /* Usecs 00:00:00 UTC, Jan 1, 1970.  */
+    
+    /* Domain Virtual Time */
+    u64                domain_time;
+       
+    /*
+     * Timeout values:
+     * Allow a domain to specify a timeout value in system time and 
+     * domain virtual time.
+     */
+    u64                wall_timeout;
+    u64                domain_timeout;
+
+    /*
+     * The index structures are all stored here for convenience. The rings 
+     * themselves are allocated by Xen but the guestos must create its own 
+     * mapping -- the machine address is given in the startinfo structure to 
+     * allow this to happen.
+     */
+    net_idx_t net_idx[MAX_DOMAIN_VIFS];
+
+    execution_context_t execution_context;
+
+} shared_info_t;
+
+/*
+ * NB. We expect that this struct is smaller than a page.
+ */
+typedef struct start_info_st {
+    /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME.     */
+    unsigned long nr_pages;      /* total pages allocated to this domain. */
+    unsigned long shared_info;   /* MACHINE address of shared info struct.*/
+    unsigned long flags;          /* SIF_xxx flags.                        */
+    /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME).      */
+    unsigned long pt_base;       /* VIRTUAL address of page directory.    */
+    unsigned long mod_start;     /* VIRTUAL address of pre-loaded module. */
+    unsigned long mod_len;       /* Size (bytes) of pre-loaded module.    */
+    unsigned char cmd_line[1];   /* Variable-length options.              */
+} start_info_t;
+
+/* These flags are passed in the 'flags' field of start_info_t. */
+#define SIF_PRIVILEGED 1          /* Is the domain privileged? */
+#define SIF_INITDOMAIN 2          /* Is thsi the initial control domain? */
+
+/* For use in guest OSes. */
+extern shared_info_t *HYPERVISOR_shared_info;
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __HYPERVISOR_IF_H__ */
index bfd99a07258ef92242cdbb1ac9a12becb0c27f32..88a1186f25f197ab457a9066c8401ef1abefcd59 100644 (file)
@@ -6,165 +6,6 @@
 
 #ifndef __XENO_CONFIG_H__
 #define __XENO_CONFIG_H__
-
-#define CONFIG_X86 1
-
-#define CONFIG_SMP 1
-#define CONFIG_X86_LOCAL_APIC 1
-#define CONFIG_X86_IO_APIC 1
-#define CONFIG_X86_L1_CACHE_SHIFT 5
-
-#define CONFIG_PCI 1
-#define CONFIG_PCI_BIOS 1
-#define CONFIG_PCI_DIRECT 1
-
-#define CONFIG_IDE 1
-#define CONFIG_BLK_DEV_IDE 1
-#define CONFIG_BLK_DEV_IDEDMA 1
-#define CONFIG_BLK_DEV_IDEPCI 1
-#define CONFIG_IDEDISK_MULTI_MODE 1
-#define CONFIG_IDEDISK_STROKE 1
-#define CONFIG_IDEPCI_SHARE_IRQ 1
-#define CONFIG_BLK_DEV_IDEDMA_PCI 1
-#define CONFIG_IDEDMA_PCI_AUTO 1
-#define CONFIG_IDEDMA_AUTO 1
-#define CONFIG_IDEDMA_ONLYDISK 1
-#define CONFIG_BLK_DEV_IDE_MODES 1
-#define CONFIG_BLK_DEV_PIIX 1
-
-#define CONFIG_SCSI 1
-#define CONFIG_SCSI_LOGGING 1
-#define CONFIG_BLK_DEV_SD 1
-#define CONFIG_SD_EXTRA_DEVS 40
-#define CONFIG_SCSI_MULTI_LUN 1
-
-#define CONFIG_XEN_ATTENTION_KEY 1
-
-#define HZ 100
-
-/*
- * Just to keep compiler happy.
- * NB. DO NOT CHANGE SMP_CACHE_BYTES WITHOUT FIXING arch/i386/entry.S!!!
- * It depends on size of irq_cpustat_t, for example, being 64 bytes. :-)
- * Mmmm... so niiiiiice....
- */
-#define SMP_CACHE_BYTES 64
-#define NR_CPUS 16
-#define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
-#define ____cacheline_aligned __cacheline_aligned
-
-/*** Hypervisor owns top 64MB of virtual address space. ***/
-#define HYPERVISOR_VIRT_START (0xFC000000UL)
-
-/*
- * First 4MB are mapped read-only for all. It's for the machine->physical
- * mapping table (MPT table). The following are virtual addresses.
- */
-#define READONLY_MPT_VIRT_START (HYPERVISOR_VIRT_START)
-#define READONLY_MPT_VIRT_END   (READONLY_MPT_VIRT_START + (4*1024*1024))
-/*
- * Next 16MB is fixed monitor space, which is part of a 44MB direct-mapped
- * memory region. The following are machine addresses.
- */
-#define MAX_MONITOR_ADDRESS   (16*1024*1024)
-#define MAX_DMA_ADDRESS       (16*1024*1024)
-#define MAX_DIRECTMAP_ADDRESS (44*1024*1024)
-/* And the virtual addresses for the direct-map region... */
-#define DIRECTMAP_VIRT_START  (READONLY_MPT_VIRT_END)
-#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
-#define MONITOR_VIRT_START    (DIRECTMAP_VIRT_START)
-#define MONITOR_VIRT_END      (MONITOR_VIRT_START + MAX_MONITOR_ADDRESS)
-#define RDWR_MPT_VIRT_START   (MONITOR_VIRT_END)
-#define RDWR_MPT_VIRT_END     (RDWR_MPT_VIRT_START + (4*1024*1024))
-#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
-#define FRAMETABLE_VIRT_END   (DIRECTMAP_VIRT_END)
-/* Next 4MB of virtual address space is used as a linear p.t. mapping. */
-#define LINEAR_PT_VIRT_START  (DIRECTMAP_VIRT_END)
-#define LINEAR_PT_VIRT_END    (LINEAR_PT_VIRT_START + (4*1024*1024))
-/* Next 4MB of virtual address space used for per-domain mappings (eg. GDT). */
-#define PERDOMAIN_VIRT_START  (LINEAR_PT_VIRT_END)
-#define PERDOMAIN_VIRT_END    (PERDOMAIN_VIRT_START + (4*1024*1024))
-#define GDT_VIRT_START        (PERDOMAIN_VIRT_START)
-#define GDT_VIRT_END          (GDT_VIRT_START + (64*1024))
-#define LDT_VIRT_START        (GDT_VIRT_END)
-#define LDT_VIRT_END          (LDT_VIRT_START + (64*1024))
-/* Penultimate 4MB of virtual address space used for domain page mappings. */
-#define MAPCACHE_VIRT_START   (PERDOMAIN_VIRT_END)
-#define MAPCACHE_VIRT_END     (MAPCACHE_VIRT_START + (4*1024*1024))
-/* Final 4MB of virtual address space used for ioremap(). */
-#define IOREMAP_VIRT_START    (MAPCACHE_VIRT_END)
-#define IOREMAP_VIRT_END      (IOREMAP_VIRT_START + (4*1024*1024))
-
-/*
- * Amount of slack domain memory to leave in system, in megabytes.
- * Prevents a hard out-of-memory crunch for thinsg like network receive.
- */
-#define SLACK_DOMAIN_MEM_KILOBYTES 2048
-
-/* Linkage for x86 */
-#define FASTCALL(x)     x __attribute__((regparm(3)))
-#define asmlinkage        __attribute__((regparm(0)))
-#define __ALIGN .align 16,0x90
-#define __ALIGN_STR ".align 16,0x90"
-#define SYMBOL_NAME_STR(X) #X
-#define SYMBOL_NAME(X) X
-#define SYMBOL_NAME_LABEL(X) X##:
-#ifdef __ASSEMBLY__
-#define ALIGN __ALIGN
-#define ALIGN_STR __ALIGN_STR
-#define ENTRY(name) \
-  .globl SYMBOL_NAME(name); \
-  ALIGN; \
-  SYMBOL_NAME_LABEL(name)
-#endif
-
-/* syslog levels ==> nothing! */
-#define KERN_NOTICE  ""
-#define KERN_WARNING ""
-#define KERN_DEBUG   ""
-#define KERN_INFO    ""
-#define KERN_ERR     ""
-#define KERN_CRIT    ""
-#define KERN_EMERG   ""
-#define KERN_ALERT   ""
-
-#define barrier() __asm__ __volatile__("": : :"memory")
-
-#define __HYPERVISOR_CS 0x0808
-#define __HYPERVISOR_DS 0x0810
-
-#define NR_syscalls 256
-
-#define offsetof(_p,_f) ((unsigned long)&(((_p *)0)->_f))
-#define struct_cpy(_x,_y) (memcpy((_x),(_y),sizeof(*(_x))))
-
-#define dev_probe_lock() ((void)0)
-#define dev_probe_unlock() ((void)0)
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define capable(_c) 0
-
-#ifndef NDEBUG
-#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
-                           __FILE__ , __LINE__ , ## _a )
-#define MEMORY_GUARD
-#define TRACE_BUFFER
-#else
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
-
-#ifndef __ASSEMBLY__
-
-#include <xeno/compiler.h>
-
-extern unsigned long _end; /* standard ELF symbol */
-extern void __out_of_line_bug(int line) __attribute__((noreturn));
-#define out_of_line_bug() __out_of_line_bug(__LINE__)
-
-extern unsigned int opt_ser_baud;
-#define SERIAL_ENABLED (opt_ser_baud != 0)
-
-#endif /* __ASSEMBLY__ */
+#include <asm/config.h>
 
 #endif /* __XENO_CONFIG_H__ */